diff options
author | dslomov@chromium.org <dslomov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 09:11:16 +0000 |
---|---|---|
committer | dslomov@chromium.org <dslomov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 09:11:16 +0000 |
commit | 1c1ef683fea483a98a819c350e82ac4dca84fa6a (patch) | |
tree | 78f20c8d8f0c32f7d37c727119984b57e85173cc /gpu | |
parent | d2c08b7abc9d737017507034095b82528e0cef65 (diff) | |
download | chromium_src-1c1ef683fea483a98a819c350e82ac4dca84fa6a.zip chromium_src-1c1ef683fea483a98a819c350e82ac4dca84fa6a.tar.gz chromium_src-1c1ef683fea483a98a819c350e82ac4dca84fa6a.tar.bz2 |
Revert 209625 "Perform glReadPixels with PBOs in the gpu, if PBO..."
Looks like it causes OutOfProcessPPAPITest.Graphics3D failure on XP.
http://build.chromium.org/p/chromium.win/builders/XP%20Tests%20%28dbg%29%282%29/builds/31095
> Perform glReadPixels with PBOs in the gpu, if PBOs are available.
> Make GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM wait for readpixel transfers.
> Add signalQuery to get a callback when the transfer is done.
> PLEASE NOTE: glMapBuffer does not wait for the readpixels transfer to complete anymore.
> Nobody is currently relying on that behaviour.
> Update gl_helper.cc and gl_renderer.cc to use queries.
>
> BUG=249925
>
> Review URL: https://chromiumcodereview.appspot.com/16831004
TBR=hubbe@chromium.org
Review URL: https://codereview.chromium.org/18445004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209654 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
19 files changed, 99 insertions, 323 deletions
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index 433242c..2568074 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -339,9 +339,6 @@ typedef void (GL_APIENTRYP PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC) ( #ifndef GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM #define GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM 0x84F5 #endif -#ifndef GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM -#define GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM 0x84F6 -#endif #endif /* GL_CHROMIUM_async_pixel_transfers */ /* GL_CHROMIUM_copy_texture */ diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index af49a93..d3fa65a 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -826,7 +826,6 @@ _ENUM_LISTS = { 'GL_COMMANDS_ISSUED_CHROMIUM', 'GL_LATENCY_QUERY_CHROMIUM', 'GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM', - 'GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM', ], }, 'RenderBufferParameter': { @@ -1902,8 +1901,7 @@ _FUNCTION_INFO = { 'GLint x, GLint y, GLsizei width, GLsizei height, ' 'GLenumReadPixelFormat format, GLenumReadPixelType type, ' 'uint32 pixels_shm_id, uint32 pixels_shm_offset, ' - 'uint32 result_shm_id, uint32 result_shm_offset, ' - 'GLboolean async', + 'uint32 result_shm_id, uint32 result_shm_offset', 'result': ['uint32'], 'defer_reads': True, }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 9c2898e..a290365 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -923,12 +923,12 @@ void ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, uint32 pixels_shm_id, uint32 pixels_shm_offset, - uint32 result_shm_id, uint32 result_shm_offset, GLboolean async) { + uint32 result_shm_id, uint32 result_shm_offset) { gles2::cmds::ReadPixels* c = GetCmdSpace<gles2::cmds::ReadPixels>(); if (c) { c->Init( x, y, width, height, format, type, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, async); + result_shm_id, result_shm_offset); } } diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 57dd4e0..fbc92d5 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -2236,7 +2236,8 @@ void GLES2Implementation::ReadPixels( if (buffer && buffer->shm_id() != -1) { helper_->ReadPixels(xoffset, yoffset, width, height, format, type, buffer->shm_id(), buffer->shm_offset(), - 0, 0, true); + 0, 0); + buffer->set_transfer_ready_token(helper_->InsertToken()); CheckGLError(); } return; @@ -2268,8 +2269,7 @@ void GLES2Implementation::ReadPixels( helper_->ReadPixels( xoffset, yoffset, width, num_rows, format, type, buffer.shm_id(), buffer.offset(), - GetResultShmId(), GetResultShmOffset(), - false); + GetResultShmId(), GetResultShmOffset()); WaitForCmd(); if (*result != 0) { // when doing a y-flip we have to iterate through top-to-bottom chunks @@ -3175,31 +3175,36 @@ void GLES2Implementation::DeleteQueriesEXTHelper( return; } // When you delete a query you can't mark its memory as unused until it's - // either completed, or deleted in the gpu process. + // completed. // Note: If you don't do this you won't mess up the service but you will mess // up yourself. + // TODO(gman): Consider making this faster by putting pending quereies + // on some queue to be removed when they are finished. bool query_pending = false; for (GLsizei ii = 0; ii < n; ++ii) { QueryTracker::Query* query = query_tracker_->GetQuery(queries[ii]); - if (query && !query->CheckResultsAvailable(helper_)) { + if (query && query->Pending()) { query_pending = true; break; } } - helper_->DeleteQueriesEXTImmediate(n, queries); - if (query_pending) { - // This should make sure that the GPU process have deleted the queries - // and given up any claim on the shared memory that goes along with - // those queries so that we can safely re-use the shared memory. WaitForCmd(); } for (GLsizei ii = 0; ii < n; ++ii) { + QueryTracker::Query* query = query_tracker_->GetQuery(queries[ii]); + if (query && query->Pending()) { + if (!query->CheckResultsAvailable(helper_)) { + // Should only get here on context lost. + MustBeContextLost(); + } + } query_tracker_->RemoveQuery(queries[ii], helper_->IsContextLost()); } + helper_->DeleteQueriesEXTImmediate(n, queries); } // TODO(gman): Remove this. Queries are not shared resources. diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index bdbde8f..7208425 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -1438,12 +1438,11 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { Cmds expected; expected.read1.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - mem1.id, mem1.offset, result1.id, result1.offset, - false); + mem1.id, mem1.offset, result1.id, result1.offset); expected.set_token1.Init(GetNextToken()); expected.read2.Init( 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - mem2.id, mem2.offset, result2.id, result2.offset, false); + mem2.id, mem2.offset, result2.id, result2.offset); expected.set_token2.Init(GetNextToken()); scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); @@ -1475,7 +1474,7 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) { Cmds expected; expected.read.Init( 0, 0, kWidth, kHeight, kFormat, kType, - mem1.id, mem1.offset, result1.id, result1.offset, false); + mem1.id, mem1.offset, result1.id, result1.offset); expected.set_token.Init(GetNextToken()); scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); diff --git a/gpu/command_buffer/client/query_tracker.cc b/gpu/command_buffer/client/query_tracker.cc index 7cd1ae8..76ebf72 100644 --- a/gpu/command_buffer/client/query_tracker.cc +++ b/gpu/command_buffer/client/query_tracker.cc @@ -113,7 +113,9 @@ void QueryTracker::Query::Begin(GLES2Implementation* gl) { gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); break; case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: - case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: + // tell service about id, shared memory and count + gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); + break; default: // tell service about id, shared memory and count gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); @@ -163,7 +165,8 @@ bool QueryTracker::Query::CheckResultsAvailable( static_cast<uint64>(0xFFFFFFFFL)); break; case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: - case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: + result_ = info_.sync->result; + break; default: result_ = info_.sync->result; break; diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 504c445..12fc743 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -4887,7 +4887,7 @@ struct ReadPixels { void Init( GLint _x, GLint _y, GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, uint32 _pixels_shm_id, uint32 _pixels_shm_offset, - uint32 _result_shm_id, uint32 _result_shm_offset, GLboolean _async) { + uint32 _result_shm_id, uint32 _result_shm_offset) { SetHeader(); x = _x; y = _y; @@ -4899,18 +4899,17 @@ struct ReadPixels { pixels_shm_offset = _pixels_shm_offset; result_shm_id = _result_shm_id; result_shm_offset = _result_shm_offset; - async = _async; } void* Set( void* cmd, GLint _x, GLint _y, GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, uint32 _pixels_shm_id, uint32 _pixels_shm_offset, uint32 _result_shm_id, - uint32 _result_shm_offset, GLboolean _async) { + uint32 _result_shm_offset) { static_cast<ValueType*>( cmd)->Init( _x, _y, _width, _height, _format, _type, _pixels_shm_id, - _pixels_shm_offset, _result_shm_id, _result_shm_offset, _async); + _pixels_shm_offset, _result_shm_id, _result_shm_offset); return NextCmdAddress<ValueType>(cmd); } @@ -4925,11 +4924,10 @@ struct ReadPixels { uint32 pixels_shm_offset; uint32 result_shm_id; uint32 result_shm_offset; - uint32 async; }; -COMPILE_ASSERT(sizeof(ReadPixels) == 48, - Sizeof_ReadPixels_is_not_48); +COMPILE_ASSERT(sizeof(ReadPixels) == 44, + Sizeof_ReadPixels_is_not_44); COMPILE_ASSERT(offsetof(ReadPixels, header) == 0, OffsetOf_ReadPixels_header_not_0); COMPILE_ASSERT(offsetof(ReadPixels, x) == 4, @@ -4952,8 +4950,6 @@ COMPILE_ASSERT(offsetof(ReadPixels, result_shm_id) == 36, OffsetOf_ReadPixels_result_shm_id_not_36); COMPILE_ASSERT(offsetof(ReadPixels, result_shm_offset) == 40, OffsetOf_ReadPixels_result_shm_offset_not_40); -COMPILE_ASSERT(offsetof(ReadPixels, async) == 44, - OffsetOf_ReadPixels_async_not_44); struct ReleaseShaderCompiler { typedef ReleaseShaderCompiler ValueType; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 8bb1ec0..b23b569 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -1803,8 +1803,7 @@ TEST_F(GLES2FormatTest, ReadPixels) { static_cast<uint32>(17), static_cast<uint32>(18), static_cast<uint32>(19), - static_cast<uint32>(20), - static_cast<GLboolean>(21)); + static_cast<uint32>(20)); EXPECT_EQ(static_cast<uint32>(cmds::ReadPixels::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -1818,7 +1817,6 @@ TEST_F(GLES2FormatTest, ReadPixels) { EXPECT_EQ(static_cast<uint32>(18), cmd.pixels_shm_offset); EXPECT_EQ(static_cast<uint32>(19), cmd.result_shm_id); EXPECT_EQ(static_cast<uint32>(20), cmd.result_shm_offset); - EXPECT_EQ(static_cast<GLboolean>(21), cmd.async); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd)); } 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 3c3fb33..36975dd 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -86,7 +86,6 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x2601, "GL_LINEAR", }, { 0x8C03, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG", }, { 0x9242, "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM", }, - { 0x88BA, "GL_READ_WRITE", }, { 0x88BB, "GL_BUFFER_ACCESS_OES", }, { 0x88BC, "GL_BUFFER_MAPPED_OES", }, { 0x88BD, "GL_BUFFER_MAP_POINTER_OES", }, @@ -228,7 +227,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x84F5, "GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM", }, { 0x882A, "GL_DRAW_BUFFER5_NV", }, { 0x80AA, "GL_SAMPLE_COVERAGE_VALUE", }, - { 0x84F6, "GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM", }, + { 0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_ARB", }, { 0x80AB, "GL_SAMPLE_COVERAGE_INVERT", }, { 0x8FC4, "GL_SHADER_BINARY_VIV", }, { 0x882B, "GL_DRAW_BUFFER6_NV", }, @@ -1080,8 +1079,6 @@ std::string GLES2Util::GetStringQueryTarget(uint32 value) { { GL_LATENCY_QUERY_CHROMIUM, "GL_LATENCY_QUERY_CHROMIUM" }, { GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, "GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM" }, - { GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM, - "GL_ASYNC_READ_PIXELS_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 396311c..5d95848 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -117,8 +117,7 @@ FeatureInfo::FeatureFlags::FeatureFlags() enable_shader_name_hashing(false), enable_samplers(false), ext_draw_buffers(false), - ext_frag_depth(false), - use_async_readpixels(false) { + ext_frag_depth(false) { } FeatureInfo::Workarounds::Workarounds() : @@ -624,16 +623,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"); diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 87abfba..3754a3c 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -45,7 +45,6 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool enable_samplers; bool ext_draw_buffers; bool ext_frag_depth; - bool use_async_readpixels; }; struct Workarounds { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 70837bf..6ed619c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -59,7 +59,6 @@ #include "gpu/command_buffer/service/vertex_array_manager.h" #include "gpu/command_buffer/service/vertex_attrib_manager.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_fence.h" #include "ui/gl/gl_image.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" @@ -478,19 +477,6 @@ class BackFramebuffer { DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); }; -struct FenceCallback { - explicit FenceCallback() - : fence(gfx::GLFence::Create()) { - DCHECK(fence); - } - void AddCallback(base::Closure cb) { - callbacks.push_back(cb); - } - std::vector<base::Closure> callbacks; - scoped_ptr<gfx::GLFence> fence; -}; - - // } // anonymous namespace. bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, @@ -601,8 +587,6 @@ class GLES2DecoderImpl : public GLES2Decoder { virtual bool HasMoreIdleWork() OVERRIDE; virtual void PerformIdleWork() OVERRIDE; - virtual void WaitForReadPixels(base::Closure callback) OVERRIDE; - virtual void SetResizeCallback( const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; @@ -1575,9 +1559,6 @@ class GLES2DecoderImpl : public GLES2Decoder { surface_->DeferDraws(); } - void ProcessPendingReadPixels(); - void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); - void ForceCompileShaderIfPending(Shader* shader); // Generate a member function prototype for each command in an automated and @@ -1745,8 +1726,6 @@ class GLES2DecoderImpl : public GLES2Decoder { scoped_ptr<GPUTracer> gpu_tracer_; - std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; - DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); }; @@ -2826,7 +2805,6 @@ bool GLES2DecoderImpl::MakeCurrent() { } void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { - ProcessPendingReadPixels(); if (engine() && query_manager_.get()) query_manager_->ProcessPendingTransferQueries(); @@ -3555,7 +3533,6 @@ bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { void GLES2DecoderImpl::DoFinish() { glFinish(); - ProcessPendingReadPixels(); ProcessPendingQueries(); } @@ -6718,96 +6695,6 @@ error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( return error::kNoError; } -void GLES2DecoderImpl::FinishReadPixels( - const cmds::ReadPixels& c, - GLuint buffer) { - TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); - GLsizei width = c.width; - GLsizei height = c.height; - GLenum format = c.format; - GLenum type = c.type; - typedef cmds::ReadPixels::Result Result; - uint32 pixels_size; - Result* result = NULL; - if (c.result_shm_id != 0) { - result = GetSharedMemoryAs<Result*>( - c.result_shm_id, c.result_shm_offset, sizeof(*result)); - if (!result) { - if (buffer != 0) { - glDeleteBuffersARB(1, &buffer); - } - return; - } - } - GLES2Util::ComputeImageDataSizes( - width, height, format, type, state_.pack_alignment, &pixels_size, - NULL, NULL); - void* pixels = GetSharedMemoryAs<void*>( - c.pixels_shm_id, c.pixels_shm_offset, pixels_size); - if (!pixels) { - if (buffer != 0) { - glDeleteBuffersARB(1, &buffer); - } - return; - } - - if (buffer != 0) { - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); - void* 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. - glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - glDeleteBuffersARB(1, &buffer); - } - - if (result != NULL) { - *result = true; - } - - GLenum read_format = GetBoundReadFrameBufferInternalFormat(); - uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); - if ((channels_exist & 0x0008) == 0 && - workarounds().clear_alpha_in_readpixels) { - // Set the alpha to 255 because some drivers are buggy in this regard. - uint32 temp_size; - - uint32 unpadded_row_size; - uint32 padded_row_size; - if (!GLES2Util::ComputeImageDataSizes( - width, 2, format, type, state_.pack_alignment, &temp_size, - &unpadded_row_size, &padded_row_size)) { - return; - } - // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time - // of this implementation. - if (type != GL_UNSIGNED_BYTE) { - return; - } - switch (format) { - case GL_RGBA: - case GL_BGRA_EXT: - case GL_ALPHA: { - int offset = (format == GL_ALPHA) ? 0 : 3; - int step = (format == GL_ALPHA) ? 1 : 4; - uint8* dst = static_cast<uint8*>(pixels) + offset; - for (GLint yy = 0; yy < height; ++yy) { - uint8* end = dst + unpadded_row_size; - for (uint8* d = dst; d < end; d += step) { - *d = 255; - } - dst += padded_row_size; - } - break; - } - default: - break; - } - } -} - - error::Error GLES2DecoderImpl::HandleReadPixels( uint32 immediate_data_size, const cmds::ReadPixels& c) { if (ShouldDeferReads()) @@ -6818,7 +6705,6 @@ error::Error GLES2DecoderImpl::HandleReadPixels( GLsizei height = c.height; GLenum format = c.format; GLenum type = c.type; - GLboolean async = c.async; if (width < 0 || height < 0) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); return error::kNoError; @@ -6918,25 +6804,6 @@ error::Error GLES2DecoderImpl::HandleReadPixels( dst += padded_row_size; } } else { - if (async && features().use_async_readpixels) { - GLuint buffer; - glGenBuffersARB(1, &buffer); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); - GLenum error = glGetError(); - if (error == GL_NO_ERROR) { - glReadPixels(x, y, width, height, format, type, 0); - pending_readpixel_fences_.push(linked_ptr<FenceCallback>( - new FenceCallback())); - WaitForReadPixels(base::Bind( - &GLES2DecoderImpl::FinishReadPixels, - base::internal::SupportsWeakPtrBase::StaticAsWeakPtr - <GLES2DecoderImpl>(this), - c, buffer)); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - return error::kNoError; - } - } glReadPixels(x, y, width, height, format, type, pixels); } GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); @@ -6944,7 +6811,51 @@ error::Error GLES2DecoderImpl::HandleReadPixels( if (result != NULL) { *result = true; } - FinishReadPixels(c, 0); + + GLenum read_format = GetBoundReadFrameBufferInternalFormat(); + uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); + if ((channels_exist & 0x0008) == 0 && + workarounds().clear_alpha_in_readpixels) { + // Set the alpha to 255 because some drivers are buggy in this regard. + uint32 temp_size; + + uint32 unpadded_row_size; + uint32 padded_row_size; + if (!GLES2Util::ComputeImageDataSizes( + width, 2, format, type, state_.pack_alignment, &temp_size, + &unpadded_row_size, &padded_row_size)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); + return error::kNoError; + } + // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time + // of this implementation. + if (type != GL_UNSIGNED_BYTE) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, "glReadPixels", + "unsupported readPixel format"); + return error::kNoError; + } + switch (format) { + case GL_RGBA: + case GL_BGRA_EXT: + case GL_ALPHA: { + int offset = (format == GL_ALPHA) ? 0 : 3; + int step = (format == GL_ALPHA) ? 1 : 4; + uint8* dst = static_cast<uint8*>(pixels) + offset; + for (GLint yy = 0; yy < height; ++yy) { + uint8* end = dst + unpadded_row_size; + for (uint8* d = dst; d < end; d += step) { + *d = 255; + } + dst += padded_row_size; + } + break; + } + default: + break; + } + } } return error::kNoError; @@ -9174,35 +9085,11 @@ bool GLES2DecoderImpl::ProcessPendingQueries() { return query_manager_->HavePendingQueries(); } -// Note that if there are no pending readpixels right now, -// this function will call the callback immediately. -void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) { - if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) { - pending_readpixel_fences_.back()->callbacks.push_back(callback); - } else { - callback.Run(); - } -} - -void GLES2DecoderImpl::ProcessPendingReadPixels() { - while (!pending_readpixel_fences_.empty() && - pending_readpixel_fences_.front()->fence->HasCompleted()) { - std::vector<base::Closure> callbacks = - pending_readpixel_fences_.front()->callbacks; - pending_readpixel_fences_.pop(); - for (size_t i = 0; i < callbacks.size(); i++) { - callbacks[i].Run(); - } - } -} - bool GLES2DecoderImpl::HasMoreIdleWork() { - return !pending_readpixel_fences_.empty() || - async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); + return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); } void GLES2DecoderImpl::PerformIdleWork() { - ProcessPendingReadPixels(); if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) return; async_pixel_transfer_manager_->ProcessMorePendingTransfers(); @@ -9220,7 +9107,6 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT( case GL_COMMANDS_ISSUED_CHROMIUM: case GL_LATENCY_QUERY_CHROMIUM: case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: - case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: case GL_GET_ERROR_QUERY_CHROMIUM: break; default: @@ -9233,8 +9119,6 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT( break; } - // TODO(hubbe): Make it possible to have one query per type running at the - // same time. if (state_.current_query.get()) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 76d61ea..97c8f58 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -213,7 +213,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, virtual void SetWaitSyncPointCallback( const WaitSyncPointCallback& callback) = 0; - virtual void WaitForReadPixels(base::Closure callback) = 0; virtual uint32 GetTextureUploadCount() = 0; virtual base::TimeDelta GetTotalTextureUploadTime() = 0; virtual base::TimeDelta GetTotalProcessingCommandsTime() = 0; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 5050518..abac629 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -102,8 +102,6 @@ class MockGLES2Decoder : public GLES2Decoder { void(const ShaderCacheCallback& callback)); MOCK_METHOD1(SetWaitSyncPointCallback, void(const WaitSyncPointCallback& callback)); - MOCK_METHOD1(WaitForReadPixels, - void(base::Closure callback)); MOCK_METHOD0(GetTextureUploadCount, uint32()); MOCK_METHOD0(GetTotalTextureUploadTime, base::TimeDelta()); MOCK_METHOD0(GetTotalProcessingCommandsTime, base::TimeDelta()); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index b426286..09ed184 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -2316,8 +2316,7 @@ void GLES2DecoderTest::CheckReadPixelsOutOfRange( cmd.Init(in_read_x, in_read_y, in_read_width, in_read_height, kFormat, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1); @@ -2394,8 +2393,7 @@ TEST_F(GLES2DecoderTest, ReadPixels) { ReadPixels cmd; cmd.Init(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); for (GLint yy = 0; yy < kHeight; ++yy) { EXPECT_TRUE(emu.CompareRowSegment( @@ -2442,8 +2440,7 @@ TEST_F(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) { ReadPixels cmd; cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); for (GLint yy = 0; yy < kHeight; ++yy) { EXPECT_TRUE(emu.CompareRowSegment( @@ -2480,41 +2477,34 @@ TEST_F(GLES2DecoderTest, ReadPixelsInvalidArgs) { ReadPixels cmd; cmd.Init(0, 0, -1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); cmd.Init(0, 0, 1, -1, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); cmd.Init(0, 0, 1, 1, GL_RGB, GL_INT, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kInvalidSharedMemoryId, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, kInvalidSharedMemoryOffset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - kInvalidSharedMemoryId, result_shm_offset, - false); + kInvalidSharedMemoryId, result_shm_offset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, kInvalidSharedMemoryOffset, - false); + result_shm_id, kInvalidSharedMemoryOffset); EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } @@ -4942,8 +4932,7 @@ TEST_F(GLES2DecoderTest, ReadPixelsGLError) { ReadPixels cmd; cmd.Init(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); } @@ -6675,9 +6664,8 @@ TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) { uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result); ReadPixels cmd; cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, - pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + pixels_shm_id, pixels_shm_offset, + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } @@ -6736,9 +6724,8 @@ TEST_F(GLES2DecoderManualInitTest, uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result); ReadPixels cmd; cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, - pixels_shm_id, pixels_shm_offset, - result_shm_id, result_shm_offset, - false); + pixels_shm_id, pixels_shm_offset, + result_shm_id, result_shm_offset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } 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 db9725d..ebe7e07 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -300,7 +300,6 @@ static GLenum valid_query_target_table[] = { GL_COMMANDS_ISSUED_CHROMIUM, GL_LATENCY_QUERY_CHROMIUM, GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, - GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM, }; static GLenum valid_read_pixel_format_table[] = { diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index 6d2f84a..e66478a 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc @@ -223,8 +223,9 @@ bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) { // on the current thread. manager()->decoder()->GetAsyncPixelTransferManager()->AsyncNotifyCompletion( mem_params, - base::Bind(&AsyncPixelTransfersCompletedQuery::MarkAsCompletedThreadSafe, + base::Bind(AsyncPixelTransfersCompletedQuery::MarkAsCompletedThreadSafe, submit_count)); + return AddToPendingTransferQueue(submit_count); } @@ -253,58 +254,6 @@ void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { } -class AsyncReadPixelsCompletedQuery - : public QueryManager::Query, - public base::SupportsWeakPtr<AsyncReadPixelsCompletedQuery> { - public: - AsyncReadPixelsCompletedQuery( - QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); - - virtual bool Begin() OVERRIDE; - virtual bool End(uint32 submit_count) OVERRIDE; - virtual bool Process() OVERRIDE; - virtual void Destroy(bool have_context) OVERRIDE; - - protected: - void Complete(); - virtual ~AsyncReadPixelsCompletedQuery(); -}; - -AsyncReadPixelsCompletedQuery::AsyncReadPixelsCompletedQuery( - QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) - : Query(manager, target, shm_id, shm_offset) { -} - -bool AsyncReadPixelsCompletedQuery::Begin() { - return true; -} - -bool AsyncReadPixelsCompletedQuery::End(uint32 submit_count) { - manager()->decoder()->WaitForReadPixels( - base::Bind(&AsyncReadPixelsCompletedQuery::Complete, - AsWeakPtr())); - - return AddToPendingTransferQueue(submit_count); -} - -void AsyncReadPixelsCompletedQuery::Complete() { - MarkAsCompleted(1); -} - -bool AsyncReadPixelsCompletedQuery::Process() { - return !pending(); -} - -void AsyncReadPixelsCompletedQuery::Destroy(bool /* have_context */) { - if (!IsDeleted()) { - MarkAsDeleted(); - } -} - -AsyncReadPixelsCompletedQuery::~AsyncReadPixelsCompletedQuery() { -} - - class GetErrorQuery : public QueryManager::Query { public: GetErrorQuery( @@ -396,10 +345,6 @@ QueryManager::Query* QueryManager::CreateQuery( query = new AsyncPixelTransfersCompletedQuery( this, target, shm_id, shm_offset); break; - case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: - query = new AsyncReadPixelsCompletedQuery( - this, target, shm_id, shm_offset); - break; case GL_GET_ERROR_QUERY_CHROMIUM: query = new GetErrorQuery(this, target, shm_id, shm_offset); break; diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index 74e50e3..961aabb 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -375,23 +375,6 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( "features": [ "use_non_zero_size_for_client_side_stream_buffers" ] - }, - { - "id": 25, - "cr_bugs": [152225], - "description": - "Intel OSX drivers prior to mountain lion crashes when using PBOs", - "os": { - "type": "macosx", - "version": { - "op": "<", - "number": "10.8" - } - }, - "vendor_id": "0x8086", - "features": [ - "disable_async_readpixels" - ] } ] } @@ -399,3 +382,4 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( ); // LONG_STRING_CONST macro } // namespace gpu + diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 41ccf2e..328fca0 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h @@ -58,8 +58,6 @@ use_current_program_after_successful_link) \ GPU_OP(USE_NON_ZERO_SIZE_FOR_CLIENT_SIDE_STREAM_BUFFERS, \ use_non_zero_size_for_client_side_stream_buffers) \ - GPU_OP(DISABLE_ASYNC_READPIXELS, \ - disable_async_readpixels) \ namespace gpu { @@ -77,3 +75,4 @@ GPU_EXPORT std::string GpuDriverBugWorkaroundTypeToString( } // namespace gpu #endif // GPU_CONFIG_GPU_DRIVER_BUG_WORKAROUND_TYPE_H_ + |