summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-27 02:50:33 +0000
committersievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-27 02:50:33 +0000
commite585f9e2bbac1ee6d93c4a57c55e94fd4af8faa4 (patch)
tree9b0d5118dae1e54723eed3fb9ad7839cbefc49b2
parente1622c230f1121d79c627c7e160bc288810600cb (diff)
downloadchromium_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.cc31
-rw-r--r--gpu/command_buffer/service/feature_info.h1
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc12
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc8
-rw-r--r--gpu/command_buffer/tests/gl_tests_main.cc3
-rw-r--r--gpu/config/gpu_driver_bug_list_json.cc17
-rwxr-xr-xui/gl/generate_bindings.py7
-rw-r--r--ui/gl/gl_fence.cc3
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);
}