Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index d67fe8c8daf39c657d5324db95fb1ff457a05807..cbcc9667385223dc5358a6b161eeaa5b814b32c9 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -21,7 +21,6 @@ |
| #include "base/mac/scoped_cftyperef.h" |
| #endif |
| #include "base/memory/scoped_ptr.h" |
| -#include "base/memory/weak_ptr.h" |
| #include "base/string_number_conversions.h" |
| #include "build/build_config.h" |
| #define GLES2_GPU_SERVICE 1 |
| @@ -458,8 +457,7 @@ bool GLES2Decoder::IsAngle() { |
| // This class implements GLES2Decoder so we don't have to expose all the GLES2 |
| // cmd stuff to outside this class. |
| -class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| - public GLES2Decoder { |
| +class GLES2DecoderImpl : public GLES2Decoder { |
| public: |
| static const int kMaxLogMessages = 256; |
| @@ -731,7 +729,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| - const void * data); |
| + const void* pixels, |
| + uint32 pixels_size); |
| // Wrapper for TexImageIOSurface2DCHROMIUM. |
| void DoTexImageIOSurface2DCHROMIUM( |
| @@ -1217,9 +1216,24 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| // Gets the buffer id for a given target. |
| BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) { |
| - DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); |
| - BufferManager::BufferInfo* info = target == GL_ARRAY_BUFFER ? |
| - bound_array_buffer_ : bound_element_array_buffer_; |
| + BufferManager::BufferInfo* info = NULL; |
| + switch(target) { |
| + case GL_ARRAY_BUFFER: |
| + info = bound_array_buffer_; |
| + break; |
| + case GL_ELEMENT_ARRAY_BUFFER: |
| + info = bound_element_array_buffer_; |
| + break; |
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| + info = bound_pixel_pack_transfer_buffer_; |
| + break; |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| + info = bound_pixel_unpack_transfer_buffer_; |
| + break; |
| + default: |
| + NOTREACHED(); |
| + return NULL; |
| + } |
| return info; |
| } |
| @@ -1348,7 +1362,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| // A parent decoder can access this decoders saved offscreen frame buffer. |
| // The parent pointer is reset if the parent is destroyed. |
| - base::WeakPtr<GLES2DecoderImpl> parent_; |
| + base::WeakPtr<CommonDecoder> parent_; |
| // Current width and height of the offscreen frame buffer. |
| gfx::Size offscreen_size_; |
| @@ -1539,6 +1553,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| GLsizei viewport_width_, viewport_height_; |
| GLsizei viewport_max_width_, viewport_max_height_; |
| + // The currently bound pixel pack transfer buffer. |
| + BufferManager::BufferInfo::Ref bound_pixel_pack_transfer_buffer_; |
| + |
| + // The currently bound pixel unpack transfer buffer. |
| + BufferManager::BufferInfo::Ref bound_pixel_unpack_transfer_buffer_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
| }; |
| @@ -2389,6 +2409,12 @@ void GLES2DecoderImpl::DeleteBuffersHelper( |
| if (bound_element_array_buffer_ == buffer) { |
| bound_element_array_buffer_ = NULL; |
| } |
| + if (bound_pixel_pack_transfer_buffer_ == buffer) { |
| + bound_pixel_pack_transfer_buffer_ = NULL; |
| + } |
| + if (bound_pixel_unpack_transfer_buffer_ == buffer) { |
| + bound_pixel_unpack_transfer_buffer_ = NULL; |
| + } |
| RemoveBufferInfo(client_ids[ii]); |
| } |
| } |
| @@ -2672,10 +2698,12 @@ GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { |
| void GLES2DecoderImpl::UpdateParentTextureInfo() { |
| if (parent_) { |
| + GLES2DecoderImpl* parent_impl = static_cast<GLES2DecoderImpl*>( |
| + parent_.get()); |
| // Update the info about the offscreen saved color texture in the parent. |
| // The reference to the parent is a weak pointer and will become null if the |
| // parent is later destroyed. |
| - TextureManager* parent_texture_manager = parent_->texture_manager(); |
| + TextureManager* parent_texture_manager = parent_impl->texture_manager(); |
| parent_texture_manager->SetLevelInfo( |
| offscreen_saved_color_texture_info_, |
| GL_TEXTURE_2D, |
| @@ -2747,6 +2775,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
| texture_units_.reset(); |
| bound_array_buffer_ = NULL; |
| bound_element_array_buffer_ = NULL; |
| + bound_pixel_pack_transfer_buffer_ = NULL; |
| + bound_pixel_unpack_transfer_buffer_ = NULL; |
| current_query_ = NULL; |
| current_program_ = NULL; |
| bound_read_framebuffer_ = NULL; |
| @@ -2862,18 +2892,20 @@ bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent, |
| // parent pointer is a weak pointer so it will be null if the parent has |
| // already been destroyed. |
| if (parent_) { |
| + GLES2DecoderImpl* parent_impl = static_cast<GLES2DecoderImpl*>( |
| + parent_.get()); |
| ChildList::iterator it = std::find( |
| - parent_->children_.begin(), |
| - parent_->children_.end(), |
| + parent_impl->children_.begin(), |
| + parent_impl->children_.end(), |
| this); |
| - DCHECK(it != parent_->children_.end()); |
| - parent_->children_.erase(it); |
| + DCHECK(it != parent_impl->children_.end()); |
| + parent_impl->children_.erase(it); |
| // First check the texture has been mapped into the parent. This might not |
| // be the case if initialization failed midway through. |
| GLuint service_id = offscreen_saved_color_texture_->id(); |
| GLuint client_id = 0; |
| - if (parent_->texture_manager()->GetClientId(service_id, &client_id)) { |
| - parent_->texture_manager()->RemoveTextureInfo(client_id); |
| + if (parent_impl->texture_manager()->GetClientId(service_id, &client_id)) { |
| + parent_impl->texture_manager()->RemoveTextureInfo(client_id); |
| } |
| } |
| @@ -2904,7 +2936,7 @@ bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent, |
| new_parent_impl->texture_manager()-> |
| SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D); |
| - parent_ = new_parent_impl->AsWeakPtr(); |
| + parent_ = new_parent->AsWeakPtr(); |
| UpdateParentTextureInfo(); |
| } else { |
| @@ -3235,15 +3267,22 @@ void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { |
| switch (target) { |
| case GL_ARRAY_BUFFER: |
| bound_array_buffer_ = info; |
| + glBindBuffer(target, service_id); |
| break; |
| case GL_ELEMENT_ARRAY_BUFFER: |
| bound_element_array_buffer_ = info; |
| + glBindBuffer(target, service_id); |
| + break; |
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| + bound_pixel_pack_transfer_buffer_ = info; |
| + break; |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| + bound_pixel_unpack_transfer_buffer_ = info; |
| break; |
| default: |
| NOTREACHED(); // Validation should prevent us getting here. |
| break; |
| } |
| - glBindBuffer(target, service_id); |
| } |
| bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() { |
| @@ -3703,6 +3742,34 @@ bool GLES2DecoderImpl::GetHelper( |
| } |
| } |
| return true; |
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| + *num_written = 1; |
| + if (params) { |
| + if (bound_pixel_pack_transfer_buffer_) { |
| + GLuint client_id = 0; |
| + buffer_manager()->GetClientId( |
| + bound_pixel_pack_transfer_buffer_->service_id(), |
| + &client_id); |
| + *params = client_id; |
| + } else { |
| + *params = 0; |
| + } |
| + } |
| + return true; |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| + *num_written = 1; |
| + if (params) { |
| + if (bound_pixel_unpack_transfer_buffer_) { |
|
greggman
2012/05/24 20:56:00
note to gman: revisit. Does this support tradition
|
| + GLuint client_id = 0; |
| + buffer_manager()->GetClientId( |
| + bound_pixel_unpack_transfer_buffer_->service_id(), |
| + &client_id); |
| + *params = client_id; |
| + } else { |
| + *params = 0; |
| + } |
| + } |
| + return true; |
| case GL_FRAMEBUFFER_BINDING: |
| // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) |
| *num_written = 1; |
| @@ -6615,6 +6682,29 @@ error::Error GLES2DecoderImpl::HandleBufferData( |
| uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); |
| uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); |
| GLenum usage = static_cast<GLenum>(c.usage); |
| + |
| + switch (target) { |
| + case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
|
greggman
2012/05/24 20:56:00
style: indent
|
| + case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: { |
| + if (!validators_->buffer_usage.IsValid(usage)) { |
| + SetGLError(GL_INVALID_ENUM, "glBufferData: usage GL_INVALID_ENUM"); |
| + return error::kNoError; |
| + } |
| + if (size < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glBufferData: size < 0"); |
| + return error::kNoError; |
| + } |
| + BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); |
| + if (!info) { |
| + SetGLError(GL_INVALID_VALUE, "glBufferData: unknown buffer"); |
| + return error::kNoError; |
| + } |
| + buffer_manager()->SetInfo( |
| + info, size, usage, this, data_shm_id, data_shm_offset); |
| + return error::kNoError; |
| + } break; |
|
greggman
2012/05/24 20:56:00
style: break goes in case block
|
| + } |
| + |
| const void* data = NULL; |
| if (data_shm_id != 0 || data_shm_offset != 0) { |
| data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); |
| @@ -7014,7 +7104,13 @@ error::Error GLES2DecoderImpl::HandleTexImage2D( |
| return error::kOutOfBounds; |
| } |
| const void* pixels = NULL; |
| - if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| + if (bound_pixel_unpack_transfer_buffer_) { |
| + pixels = bound_pixel_unpack_transfer_buffer_->GetRange( |
| + pixels_shm_offset, pixels_size); |
| + if (!pixels) { |
| + return error::kOutOfBounds; |
| + } |
| + } else if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| pixels = GetSharedMemoryAs<const void*>( |
| pixels_shm_id, pixels_shm_offset, pixels_size); |
| if (!pixels) { |
| @@ -7088,6 +7184,7 @@ void GLES2DecoderImpl::DoCompressedTexSubImage2D( |
| "glCompressedTexSubImage2D: bad dimensions."); |
| return; |
| } |
| + |
| // Note: There is no need to deal with texture cleared tracking here |
| // because the validation above means you can only get here if the level |
| // is already a matching compressed format and in that case |
| @@ -7297,7 +7394,8 @@ void GLES2DecoderImpl::DoTexSubImage2D( |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| - const void * data) { |
| + const void* pixels, |
| + uint32 pixels_size) { |
|
greggman
2012/05/24 20:56:00
pixels_size doesn't appear to be used. Was there a
|
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| if (!info) { |
| SetGLError(GL_INVALID_OPERATION, |
| @@ -7341,7 +7439,7 @@ void GLES2DecoderImpl::DoTexSubImage2D( |
| return; |
| } |
| glTexSubImage2D( |
| - target, level, xoffset, yoffset, width, height, format, type, data); |
| + target, level, xoffset, yoffset, width, height, format, type, pixels); |
| return; |
| } |
| @@ -7349,10 +7447,10 @@ void GLES2DecoderImpl::DoTexSubImage2D( |
| // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| // same as internal_foramt. If that changes we'll need to look them up. |
| WrappedTexImage2D( |
| - target, level, format, width, height, 0, format, type, data); |
| + target, level, format, width, height, 0, format, type, pixels); |
| } else { |
| glTexSubImage2D( |
| - target, level, xoffset, yoffset, width, height, format, type, data); |
| + target, level, xoffset, yoffset, width, height, format, type, pixels); |
| } |
| texture_manager()->SetLevelCleared(info, target, level); |
| } |
| @@ -7377,8 +7475,6 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
| width, height, format, type, unpack_alignment_, &data_size, NULL, NULL)) { |
| return error::kOutOfBounds; |
| } |
| - const void* pixels = GetSharedMemoryAs<const void*>( |
| - c.pixels_shm_id, c.pixels_shm_offset, data_size); |
| if (!validators_->texture_target.IsValid(target)) { |
| SetGLError(GL_INVALID_ENUM, "glTexSubImage2D: target GL_INVALID_ENUM"); |
| return error::kNoError; |
| @@ -7399,11 +7495,21 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
| SetGLError(GL_INVALID_ENUM, "glTexSubImage2D: type GL_INVALID_ENUM"); |
| return error::kNoError; |
| } |
| + |
| + const void* pixels = NULL; |
| + if (bound_pixel_unpack_transfer_buffer_) { |
| + pixels = bound_pixel_unpack_transfer_buffer_->GetRange( |
| + c.pixels_shm_offset, data_size); |
| + } else { |
| + pixels = GetSharedMemoryAs<const void*>( |
| + c.pixels_shm_id, c.pixels_shm_offset, data_size); |
| + } |
| if (pixels == NULL) { |
| return error::kOutOfBounds; |
| } |
| DoTexSubImage2D( |
| - target, level, xoffset, yoffset, width, height, format, type, pixels); |
| + target, level, xoffset, yoffset, width, height, format, type, pixels, |
| + data_size); |
| return error::kNoError; |
| } |
| @@ -7452,7 +7558,8 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate( |
| return error::kOutOfBounds; |
| } |
| DoTexSubImage2D( |
| - target, level, xoffset, yoffset, width, height, format, type, pixels); |
| + target, level, xoffset, yoffset, width, height, format, type, pixels, |
| + data_size); |
| return error::kNoError; |
| } |