summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-17 23:48:27 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-17 23:48:27 +0000
commit6a25ae42f4c34047298ad5bf26ec14e6bafb5805 (patch)
tree18c94e94db86a3892a00de8fef82f324ec117b9e /gpu
parentc53d16f1736e97da9d8de7c55b2c861aab9080b2 (diff)
downloadchromium_src-6a25ae42f4c34047298ad5bf26ec14e6bafb5805.zip
chromium_src-6a25ae42f4c34047298ad5bf26ec14e6bafb5805.tar.gz
chromium_src-6a25ae42f4c34047298ad5bf26ec14e6bafb5805.tar.bz2
Re-land: gpu: Add CHROMIUM_sync_query extension.
This adds a GL_COMMANDS_COMPLETED_CHROMIUM query target that provide a finer granularity of synchronizing GL command completion than offered by glFinish(). BUG=269808,356871,273274 TEST=gpu_unittests --gtest_filter=GLES2DecoderManualInitTest.BeginEndQueryEXTCommandsCompletedCHROMIUM Review URL: https://codereview.chromium.org/238933003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@264675 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_query.txt53
-rw-r--r--gpu/GLES2/gl2extchromium.h9
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h10
-rw-r--r--gpu/command_buffer/service/feature_info.cc6
-rw-r--r--gpu/command_buffer/service/feature_info.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc8
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc76
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h3
-rw-r--r--gpu/command_buffer/service/query_manager.cc53
10 files changed, 217 insertions, 3 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_query.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_query.txt
new file mode 100644
index 0000000..98763d0
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_query.txt
@@ -0,0 +1,53 @@
+Name
+
+ CHROMIUM_sync_query
+
+Name Strings
+
+ GL_CHROMIUM_sync_query
+
+Version
+
+ Last Modifed Date: April 15, 2014
+
+Dependencies
+
+ OpenGL ES 2.0 is required.
+
+ EXT_occlusion_query_boolean is required.
+
+Overview
+
+ This extension provides a query mechanism that allow for synchronization
+ between the host CPU and the GPU, which may be accessing the same
+ resources (typically memory).
+
+ This extension is useful in conjunction with CHROMIUM_map_image to
+ determine when it is safe to access a mapped image. Once the result of
+ a COMMANDS_COMPLETED_CHROMIUM query is available, all drawing commands
+ issued before the query must have finished. This ensures that the memory
+ corresponding to the issued commands can be safely modified (assuming no
+ other outstanding drawing commands are issued subsequent to the query).
+
+New Procedures and Functions
+
+ None.
+
+Errors
+
+ None.
+
+New Tokens
+
+ Accepted by the <target> parameter of BeginQueryEXT, EndQueryEXT,
+ and GetQueryivEXT:
+
+ COMMANDS_COMPLETED_CHROMIUM 0x84F7
+
+New State
+
+ None.
+
+Revision History
+
+ 4/15/2014 Documented the extension
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h
index db4f12f..0bdf717 100644
--- a/gpu/GLES2/gl2extchromium.h
+++ b/gpu/GLES2/gl2extchromium.h
@@ -692,6 +692,15 @@ typedef void(GL_APIENTRYP PFNGLSCHEDULEOVERLAYPLANECHROMIUMPROC)(
GLfloat uv_height);
#endif /* GL_CHROMIUM_schedule_overlay_plane */
+/* GL_CHROMIUM_sync_query */
+#ifndef GL_CHROMIUM_sync_query
+#define GL_CHROMIUM_sync_query 1
+
+#ifndef GL_COMMANDS_COMPLETED_CHROMIUM
+#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
+#endif
+#endif /* GL_CHROMIUM_sync_query */
+
#ifdef __cplusplus
}
#endif
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 84d70c0..7105edf 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -841,6 +841,7 @@ _ENUM_LISTS = {
'GL_LATENCY_QUERY_CHROMIUM',
'GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM',
'GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM',
+ 'GL_COMMANDS_COMPLETED_CHROMIUM',
],
},
'RenderBufferParameter': {
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 62f1c308..e9f4f69 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -179,6 +179,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = {
{0x84F4, "GL_FENCE_CONDITION_NV", },
{0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT", },
{0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT", },
+ {0x84F7, "GL_COMMANDS_COMPLETED_CHROMIUM", },
{0x881E, "GL_LUMINANCE16F_EXT", },
{0x84FA, "GL_UNSIGNED_INT_24_8_OES", },
{0x881F, "GL_LUMINANCE_ALPHA16F_EXT", },
@@ -353,6 +354,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = {
{0x8C93, "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD", },
{0x00000002, "GL_CONTEXT_FLAG_DEBUG_BIT_KHR", },
{0x00000001, "GL_SYNC_FLUSH_COMMANDS_BIT_APPLE", },
+ {0x9248, "GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM", },
{0x00000004, "GL_COLOR_BUFFER_BIT2_QCOM", },
{0x1702, "GL_TEXTURE", },
{0x00000008, "GL_COLOR_BUFFER_BIT3_QCOM", },
@@ -385,6 +387,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = {
{0x8DF6, "GL_UNSIGNED_INT_10_10_10_2_OES", },
{0x8230, "GL_RG32F_EXT", },
{0x8DF7, "GL_INT_10_10_10_2_OES", },
+ {0x9246, "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM", },
{0x8B69, "GL_FLOAT_MAT4x2_NV", },
{0x812D, "GL_CLAMP_TO_BORDER_NV", },
{0x812F, "GL_CLAMP_TO_EDGE", },
@@ -604,8 +607,11 @@ static const GLES2Util::EnumToString enum_to_string_table[] = {
{0x1F02, "GL_VERSION", },
{0x1F01, "GL_RENDERER", },
{0x1F00, "GL_VENDOR", },
+ {0x9247, "GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM", },
{0x2701, "GL_LINEAR_MIPMAP_NEAREST", },
+ {0x9245, "GL_OVERLAY_TRANSFORM_NONE_CHROMIUM", },
{0x92B4, "GL_INVERT_OVG_NV", },
+ {0x9249, "GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM", },
{0x0B94, "GL_STENCIL_FAIL", },
{0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS", },
{0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS", },
@@ -634,6 +640,7 @@ static const GLES2Util::EnumToString enum_to_string_table[] = {
{0x1004, "GL_TEXTURE_BORDER_COLOR_NV", },
{0x8B48, "GL_SHADER_OBJECT_EXT", },
{0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT_EXT", },
+ {0x924A, "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM", },
{0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM", },
{0x0DE1, "GL_TEXTURE_2D", },
{0x80C9, "GL_BLEND_SRC_RGB", },
@@ -1163,7 +1170,8 @@ std::string GLES2Util::GetStringQueryTarget(uint32 value) {
{GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
"GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM"},
{GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM,
- "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM"}, };
+ "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM"},
+ {GL_COMMANDS_COMPLETED_CHROMIUM, "GL_COMMANDS_COMPLETED_CHROMIUM"}, };
return GLES2Util::GetQualifiedEnumString(
string_table, arraysize(string_table), value);
}
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 334cec1..15d8ca0 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -110,6 +110,7 @@ FeatureInfo::FeatureFlags::FeatureFlags()
: chromium_color_buffer_float_rgba(false),
chromium_color_buffer_float_rgb(false),
chromium_framebuffer_multisample(false),
+ chromium_sync_query(false),
use_core_framebuffer_multisample(false),
multisampled_render_to_texture(false),
use_img_for_multisampled_render_to_texture(false),
@@ -794,6 +795,11 @@ void FeatureInfo::InitializeFeatures() {
AddExtensionString("GL_EXT_discard_framebuffer");
feature_flags_.ext_discard_framebuffer = true;
}
+
+ if (ui_gl_fence_works) {
+ AddExtensionString("GL_CHROMIUM_sync_query");
+ feature_flags_.chromium_sync_query = true;
+ }
}
void FeatureInfo::AddExtensionString(const std::string& str) {
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index c29a50c..8e9c07c 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -31,6 +31,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool chromium_color_buffer_float_rgba;
bool chromium_color_buffer_float_rgb;
bool chromium_framebuffer_multisample;
+ bool chromium_sync_query;
// Use glBlitFramebuffer() and glRenderbufferStorageMultisample() with
// GL_EXT_framebuffer_multisample-style semantics, since they are exposed
// as core GL functions on this implementation.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a886513..d0b040b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -9535,6 +9535,14 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
case GL_GET_ERROR_QUERY_CHROMIUM:
break;
+ case GL_COMMANDS_COMPLETED_CHROMIUM:
+ if (!features().chromium_sync_query) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION, "glBeginQueryEXT",
+ "not enabled for commands completed queries");
+ return error::kNoError;
+ }
+ break;
default:
if (!features().occlusion_query_boolean) {
LOCAL_SET_GL_ERROR(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 19b7292..b367e5c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -7112,6 +7112,7 @@ const QueryType kQueryTypes[] = {
{ GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false },
{ GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false },
{ GL_GET_ERROR_QUERY_CHROMIUM, false },
+ { GL_COMMANDS_COMPLETED_CHROMIUM, false },
{ GL_ANY_SAMPLES_PASSED_EXT, true },
};
@@ -7125,7 +7126,7 @@ static void CheckBeginEndQueryBadMemoryFails(
// We need to reset the decoder on each iteration, because we lose the
// context every time.
GLES2DecoderTestBase::InitState init;
- init.extensions = "GL_EXT_occlusion_query_boolean";
+ init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
init.gl_version = "opengl es 2.0";
init.has_alpha = true;
init.request_alpha = true;
@@ -7160,6 +7161,13 @@ static void CheckBeginEndQueryBadMemoryFails(
.WillOnce(Return(GL_NO_ERROR))
.RetiresOnSaturation();
}
+ GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
+ if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
+ EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
+ EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
+ .WillOnce(Return(kGlSync))
+ .RetiresOnSaturation();
+ }
EndQueryEXT end_cmd;
end_cmd.Init(query_type.type, 1);
@@ -7175,6 +7183,11 @@ static void CheckBeginEndQueryBadMemoryFails(
.WillOnce(SetArgumentPointee<2>(1))
.RetiresOnSaturation();
}
+ if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
+ EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
+ .WillOnce(Return(GL_ALREADY_SIGNALED))
+ .RetiresOnSaturation();
+ }
QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
ASSERT_TRUE(query_manager != NULL);
@@ -7189,6 +7202,8 @@ static void CheckBeginEndQueryBadMemoryFails(
.Times(1)
.RetiresOnSaturation();
}
+ if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM)
+ EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
test->ResetDecoder();
}
@@ -7276,6 +7291,65 @@ TEST_F(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
static_cast<GLenum>(sync->result));
}
+TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
+ InitState init;
+ init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
+ init.gl_version = "opengl es 2.0";
+ init.has_alpha = true;
+ init.request_alpha = true;
+ init.bind_generates_resource = true;
+ InitDecoder(init);
+
+ GenHelper<GenQueriesEXTImmediate>(kNewClientId);
+
+ BeginQueryEXT begin_cmd;
+ begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
+ kNewClientId,
+ kSharedMemoryId,
+ kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ QueryManager* query_manager = decoder_->GetQueryManager();
+ ASSERT_TRUE(query_manager != NULL);
+ QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
+ ASSERT_TRUE(query != NULL);
+ EXPECT_FALSE(query->pending());
+
+ GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
+ EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
+ EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
+ .WillOnce(Return(kGlSync))
+ .RetiresOnSaturation();
+
+ EndQueryEXT end_cmd;
+ end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(query->pending());
+
+ EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
+ .WillOnce(Return(GL_TIMEOUT_EXPIRED))
+ .RetiresOnSaturation();
+ bool process_success = query_manager->ProcessPendingQueries();
+
+ EXPECT_TRUE(process_success);
+ EXPECT_TRUE(query->pending());
+
+ EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
+ .WillOnce(Return(GL_ALREADY_SIGNALED))
+ .RetiresOnSaturation();
+ process_success = query_manager->ProcessPendingQueries();
+
+ EXPECT_TRUE(process_success);
+ EXPECT_FALSE(query->pending());
+ QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
+ EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result));
+
+ EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
+ ResetDecoder();
+}
+
TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
Mailbox mailbox = Mailbox::Generate();
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index ca49ced..d296018 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -214,7 +214,8 @@ static const GLenum valid_query_target_table[] = {
GL_COMMANDS_ISSUED_CHROMIUM,
GL_LATENCY_QUERY_CHROMIUM,
GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
- GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, };
+ GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM,
+ GL_COMMANDS_COMPLETED_CHROMIUM, };
static const GLenum valid_read_pixel_format_table[] = {GL_ALPHA, GL_RGB,
GL_RGBA, };
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 9f1d3a7..30c036e 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -16,6 +16,7 @@
#include "gpu/command_buffer/service/error_state.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "ui/gl/gl_fence.h"
namespace gpu {
namespace gles2 {
@@ -389,6 +390,55 @@ void GetErrorQuery::Destroy(bool /* have_context */) {
GetErrorQuery::~GetErrorQuery() {
}
+class CommandsCompletedQuery : public QueryManager::Query {
+ public:
+ CommandsCompletedQuery(QueryManager* manager,
+ GLenum target,
+ int32 shm_id,
+ uint32 shm_offset);
+
+ // Overridden from QueryManager::Query:
+ virtual bool Begin() OVERRIDE;
+ virtual bool End(base::subtle::Atomic32 submit_count) OVERRIDE;
+ virtual bool Process() OVERRIDE;
+ virtual void Destroy(bool have_context) OVERRIDE;
+
+ protected:
+ virtual ~CommandsCompletedQuery();
+
+ private:
+ scoped_ptr<gfx::GLFence> fence_;
+};
+
+CommandsCompletedQuery::CommandsCompletedQuery(QueryManager* manager,
+ GLenum target,
+ int32 shm_id,
+ uint32 shm_offset)
+ : Query(manager, target, shm_id, shm_offset) {}
+
+bool CommandsCompletedQuery::Begin() { return true; }
+
+bool CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
+ fence_.reset(gfx::GLFence::Create());
+ DCHECK(fence_);
+ return AddToPendingQueue(submit_count);
+}
+
+bool CommandsCompletedQuery::Process() {
+ if (fence_ && !fence_->HasCompleted())
+ return true;
+ return MarkAsCompleted(0);
+}
+
+void CommandsCompletedQuery::Destroy(bool have_context) {
+ if (have_context && !IsDeleted()) {
+ fence_.reset();
+ MarkAsDeleted();
+ }
+}
+
+CommandsCompletedQuery::~CommandsCompletedQuery() {}
+
QueryManager::QueryManager(
GLES2Decoder* decoder,
FeatureInfo* feature_info)
@@ -444,6 +494,9 @@ QueryManager::Query* QueryManager::CreateQuery(
case GL_GET_ERROR_QUERY_CHROMIUM:
query = new GetErrorQuery(this, target, shm_id, shm_offset);
break;
+ case GL_COMMANDS_COMPLETED_CHROMIUM:
+ query = new CommandsCompletedQuery(this, target, shm_id, shm_offset);
+ break;
default: {
GLuint service_id = 0;
glGenQueriesARB(1, &service_id);