diff options
author | robert.bradford@intel.com <robert.bradford@intel.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-20 20:56:17 +0000 |
---|---|---|
committer | robert.bradford@intel.com <robert.bradford@intel.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-20 20:56:17 +0000 |
commit | 3d6bf4bdf0c839b8316dd720c6ceb7cb9fb2436f (patch) | |
tree | 86bc6455400a1a73c7c775700622698dfd4450f4 /gpu | |
parent | 7a60cd3a87912064436bc1f12d6b2ea3abddf961 (diff) | |
download | chromium_src-3d6bf4bdf0c839b8316dd720c6ceb7cb9fb2436f.zip chromium_src-3d6bf4bdf0c839b8316dd720c6ceb7cb9fb2436f.tar.gz chromium_src-3d6bf4bdf0c839b8316dd720c6ceb7cb9fb2436f.tar.bz2 |
GLHelper: Use preferred BGRA read pixels for YUV read back
When copying to the PBO the driver can use a blit if the requested
format matches the underlying format of the data. Mesa on Intel is
storing the data internally as BGRA (byte order).
This change moves the choice of format to the caller of the
ReadbackAsync and ReadbackPlane functions.
We then use GL_BGRA to read in the plane data for the YUV readback
object. However since the format is now swizzled we must swizzle the
pixel data back. This is done using the existing mechanism for swizzling
the result in the scaling shaders.
The activation of the use of GL_BGRA and swizzling is controlled by
querying the GL implementation for it's preferred format and type. In
the GPU code we pass this request onto the underlying GL implementation
if it supports the GL_OES_read_format extension.
As a result of this change glReadPixels can return immediately after
setting up the blit to the PBO and as such the asynchronous glReadPixels
works as expected when reading back YUV data for Tab Casting.
TEST=With the change observe that the time spent in the
HandleReadPixels tracepoint is reduced.
BUG=348015
Review URL: https://codereview.chromium.org/178583008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258402 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 9 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 128 |
2 files changed, 137 insertions, 0 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index d6f9fc8..73d8362 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -4165,6 +4165,12 @@ bool GLES2DecoderImpl::GetHelper( switch (pname) { case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *num_written = 1; + // Trigger the passthrough for _COLOR_READ_FORMAT and (see below) for + // _COLOR_READ_TYPE if we have the GL extension that exposes this. + // This allows the GPU client to use the implementation's preferred + // format for glReadPixels. + if (context_->HasExtension("GL_OES_read_format")) + return false; if (params) { *params = GLES2Util::GetPreferredGLReadPixelsFormat( GetBoundReadFrameBufferInternalFormat()); @@ -4172,6 +4178,8 @@ bool GLES2DecoderImpl::GetHelper( return true; case GL_IMPLEMENTATION_COLOR_READ_TYPE: *num_written = 1; + if (context_->HasExtension("GL_OES_read_format")) + return false; if (params) { *params = GLES2Util::GetPreferredGLReadPixelsType( GetBoundReadFrameBufferInternalFormat(), @@ -7222,6 +7230,7 @@ void GLES2DecoderImpl::FinishReadPixels( error::Error GLES2DecoderImpl::HandleReadPixels( uint32 immediate_data_size, const cmds::ReadPixels& c) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels"); error::Error fbo_error = WillAccessBoundFramebufferForRead(); if (fbo_error != error::kNoError) return fbo_error; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 15fd1d1..6f17e66 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -9204,6 +9204,134 @@ TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) { GL_LUMINANCE_ALPHA32F_ARB); } +TEST_F(GLES2DecoderManualInitTest, ReadFormatExtension) { + InitDecoder( + "GL_OES_read_format", // extensions + "2.1", // gl version + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + + typedef GetIntegerv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + GetIntegerv cmd; + const GLuint kFBOClientTextureId = 4100; + const GLuint kFBOServiceTextureId = 4101; + + // Register a texture id. + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .RetiresOnSaturation(); + GenHelper<GenTexturesImmediate>(kFBOClientTextureId); + + // Setup "render to" texture. + DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); + DoTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); + DoBindFramebuffer( + GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); + DoFramebufferTexture2D( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR); + + result->size = 0; + EXPECT_CALL(*gl_, GetIntegerv(_, _)) + .Times(1) + .RetiresOnSaturation(); + cmd.Init( + GL_IMPLEMENTATION_COLOR_READ_FORMAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + result->size = 0; + EXPECT_CALL(*gl_, GetIntegerv(_, _)) + .Times(1) + .RetiresOnSaturation(); + cmd.Init( + GL_IMPLEMENTATION_COLOR_READ_TYPE, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, NoReadFormatExtension) { + InitDecoder( + "", // extensions + "2.1", // gl version + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + + typedef GetIntegerv::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + GetIntegerv cmd; + const GLuint kFBOClientTextureId = 4100; + const GLuint kFBOServiceTextureId = 4101; + + // Register a texture id. + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId)) + .RetiresOnSaturation(); + GenHelper<GenTexturesImmediate>(kFBOClientTextureId); + + // Setup "render to" texture. + DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); + DoTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); + DoBindFramebuffer( + GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); + DoFramebufferTexture2D( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR); + + result->size = 0; + EXPECT_CALL(*gl_, GetIntegerv(_, _)) + .Times(0) + .RetiresOnSaturation(); + cmd.Init( + GL_IMPLEMENTATION_COLOR_READ_FORMAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + result->size = 0; + EXPECT_CALL(*gl_, GetIntegerv(_, _)) + .Times(0) + .RetiresOnSaturation(); + cmd.Init( + GL_IMPLEMENTATION_COLOR_READ_TYPE, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + // TODO(gman): Complete this test. // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { // } |