diff options
author | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 02:50:33 +0000 |
---|---|---|
committer | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 02:50:33 +0000 |
commit | e585f9e2bbac1ee6d93c4a57c55e94fd4af8faa4 (patch) | |
tree | 9b0d5118dae1e54723eed3fb9ad7839cbefc49b2 | |
parent | e1622c230f1121d79c627c7e160bc288810600cb (diff) | |
download | chromium_src-e585f9e2bbac1ee6d93c4a57c55e94fd4af8faa4.zip chromium_src-e585f9e2bbac1ee6d93c4a57c55e94fd4af8faa4.tar.gz chromium_src-e585f9e2bbac1ee6d93c4a57c55e94fd4af8faa4.tar.bz2 |
Support async readbacks on OpenGL ES 3.0 drivers
R=apatrick@chromium.org, hubbe@chromium.org
Review URL: https://codereview.chromium.org/22891024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@219669 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 31 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info_unittest.cc | 12 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 8 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_tests_main.cc | 3 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_list_json.cc | 17 | ||||
-rwxr-xr-x | ui/gl/generate_bindings.py | 7 | ||||
-rw-r--r-- | ui/gl/gl_fence.cc | 3 |
8 files changed, 65 insertions, 17 deletions
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 41c6a1b..453b43d 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -120,7 +120,8 @@ FeatureInfo::FeatureFlags::FeatureFlags() enable_samplers(false), ext_draw_buffers(false), ext_frag_depth(false), - use_async_readpixels(false) { + use_async_readpixels(false), + map_buffer_range(false) { } FeatureInfo::Workarounds::Workarounds() : @@ -644,16 +645,6 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) { feature_flags_.ext_frag_depth = true; } - bool ui_gl_fence_works = - extensions.Contains("GL_NV_fence") || - extensions.Contains("GL_ARB_sync"); - - if (ui_gl_fence_works && - extensions.Contains("GL_ARB_pixel_buffer_object") && - !workarounds_.disable_async_readpixels) { - feature_flags_.use_async_readpixels = true; - } - if (!disallowed_features_.swap_buffer_complete_callback) AddExtensionString("GL_CHROMIUM_swapbuffers_complete_callback"); @@ -664,6 +655,24 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) { is_es3 = (lstr.substr(0, 12) == "opengl es 3."); } + bool ui_gl_fence_works = extensions.Contains("GL_NV_fence") || + extensions.Contains("GL_ARB_sync") || + extensions.Contains("EGL_KHR_fence_sync"); + + feature_flags_.map_buffer_range = + is_es3 || extensions.Contains("GL_ARB_map_buffer_range"); + + // Really it's part of core OpenGL 2.1 and up, but let's assume the + // extension is still advertised. + bool has_pixel_buffers = + is_es3 || extensions.Contains("GL_ARB_pixel_buffer_object"); + + // We will use either glMapBuffer() or glMapBufferRange() for async readbacks. + if (has_pixel_buffers && ui_gl_fence_works && + !workarounds_.disable_async_readpixels) { + feature_flags_.use_async_readpixels = true; + } + if (is_es3 || extensions.Contains("GL_ARB_sampler_objects")) { feature_flags_.enable_samplers = true; // TODO(dsinclair): Add AddExtensionString("GL_CHROMIUM_sampler_objects") diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index a9ccf64..8b33bb1 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -49,6 +49,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool ext_draw_buffers; bool ext_frag_depth; bool use_async_readpixels; + bool map_buffer_range; }; struct Workarounds { diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 0dc1685..1d1cba4 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -96,6 +96,8 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags( ).use_arb_occlusion_query_for_occlusion_query_boolean); EXPECT_FALSE(info_->feature_flags().native_vertex_array_object); + EXPECT_FALSE(info_->feature_flags().map_buffer_range); + EXPECT_FALSE(info_->feature_flags().use_async_readpixels); #define GPU_OP(type, name) EXPECT_FALSE(info_->workarounds().name); GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) @@ -864,10 +866,12 @@ TEST_F(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { EXPECT_TRUE(info_->feature_flags().enable_samplers); } -TEST_F(FeatureInfoTest, InitializeSamplersWithES3) { +TEST_F(FeatureInfoTest, InitializeWithES3) { SetupInitExpectationsWithGLVersion("", "OpenGL ES 3.0"); info_->Initialize(NULL); EXPECT_TRUE(info_->feature_flags().enable_samplers); + EXPECT_TRUE(info_->feature_flags().map_buffer_range); + EXPECT_FALSE(info_->feature_flags().use_async_readpixels); } TEST_F(FeatureInfoTest, InitializeWithoutSamplers) { @@ -876,6 +880,12 @@ TEST_F(FeatureInfoTest, InitializeWithoutSamplers) { EXPECT_FALSE(info_->feature_flags().enable_samplers); } +TEST_F(FeatureInfoTest, InitializeWithES3AndFences) { + SetupInitExpectationsWithGLVersion("EGL_KHR_fence_sync", "OpenGL ES 3.0"); + info_->Initialize(NULL); + EXPECT_TRUE(info_->feature_flags().use_async_readpixels); +} + TEST_F(FeatureInfoTest, ParseDriverBugWorkaroundsSingle) { SetupInitExpectations(""); CommandLine command_line(0, NULL); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 77a6b8a..1cca696 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -6716,7 +6716,13 @@ void GLES2DecoderImpl::FinishReadPixels( if (buffer != 0) { glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); - void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); + void* data; + if (features().map_buffer_range) { + data = glMapBufferRange( + GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); + } else { + data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); + } memcpy(pixels, data, pixels_size); // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't // have to restore the state. diff --git a/gpu/command_buffer/tests/gl_tests_main.cc b/gpu/command_buffer/tests/gl_tests_main.cc index e6044e7..4a689a2 100644 --- a/gpu/command_buffer/tests/gl_tests_main.cc +++ b/gpu/command_buffer/tests/gl_tests_main.cc @@ -38,8 +38,7 @@ int main(int argc, char** argv) { gfx::GLSurface::InitializeOneOff(); ::gles2::Initialize(); gpu::ApplyGpuDriverBugWorkarounds(CommandLine::ForCurrentProcess()); - base::MessageLoop::Type message_loop_type = base::MessageLoop::TYPE_UI; - base::MessageLoop main_message_loop(message_loop_type); + base::MessageLoop main_message_loop; return GLTestHelper::RunTests(argc, argv); } diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index 7b2d8df..2383998 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -85,7 +85,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "2.6", + "version": "2.7", "entries": [ { "id": 1, @@ -436,6 +436,21 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( "features": [ "disable_angle_instanced_arrays" ] + }, + { + "id": 29, + "cr_bugs": [278606], + "description": "Testing fences is broken on QualComm.", + "os": { + "type": "android" + }, + "gl_vendor": { + "op": "beginwith", + "value": "Qualcomm" + }, + "features": [ + "disable_async_readpixels" + ] } ] } diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 3b37a17..3e51dcb 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py @@ -432,6 +432,13 @@ GL_FUNCTIONS = [ { 'return_type': 'void*', 'names': ['glMapBuffer', 'glMapBufferOES'], 'arguments': 'GLenum target, GLenum access', }, +{ 'return_type': 'void*', + 'names': ['glMapBufferRange'], + 'arguments': + 'GLenum target, GLintptr offset, GLsizeiptr length, GLenum access', }, +{ 'return_type': 'void', + 'names': ['glFlushMappedBufferRange'], + 'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', }, { 'return_type': 'void', 'names': ['glPixelStorei'], 'arguments': 'GLenum pname, GLint param', }, diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc index b9d9513..9b85300 100644 --- a/ui/gl/gl_fence.cc +++ b/ui/gl/gl_fence.cc @@ -80,6 +80,7 @@ class EGLFenceSync : public gfx::GLFence { EGLFenceSync() { display_ = eglGetCurrentDisplay(); sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL); + glFlush(); } virtual bool HasCompleted() OVERRIDE { @@ -90,7 +91,7 @@ class EGLFenceSync : public gfx::GLFence { } virtual void ClientWait() OVERRIDE { - EGLint flags = EGL_SYNC_FLUSH_COMMANDS_BIT_KHR; + EGLint flags = 0; EGLTimeKHR time = EGL_FOREVER_KHR; eglClientWaitSyncKHR(display_, sync_, flags, time); } |