summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorrobert.bradford@intel.com <robert.bradford@intel.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 20:56:17 +0000
committerrobert.bradford@intel.com <robert.bradford@intel.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 20:56:17 +0000
commit3d6bf4bdf0c839b8316dd720c6ceb7cb9fb2436f (patch)
tree86bc6455400a1a73c7c775700622698dfd4450f4 /gpu
parent7a60cd3a87912064436bc1f12d6b2ea3abddf961 (diff)
downloadchromium_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.cc9
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc128
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) {
// }