Chromium Code Reviews| Index: content/common/gpu/texture_image_transport_surface.cc |
| diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc |
| index 4ad192e0213517e22becf6480779fec264aa2faa..4507ef1bfcbc2888de13c3b47b73db4c1c93da9a 100644 |
| --- a/content/common/gpu/texture_image_transport_surface.cc |
| +++ b/content/common/gpu/texture_image_transport_surface.cc |
| @@ -16,17 +16,19 @@ |
| #include "content/public/common/content_switches.h" |
| #include "gpu/command_buffer/service/context_group.h" |
| #include "gpu/command_buffer/service/gpu_scheduler.h" |
| -#include "gpu/command_buffer/service/texture_manager.h" |
| +#include "gpu/command_buffer/service/texture_definition.h" |
| using gpu::gles2::ContextGroup; |
| +using gpu::gles2::MailboxManager; |
| +using gpu::gles2::MailboxName; |
| +using gpu::gles2::TextureDefinition; |
| using gpu::gles2::TextureManager; |
| -typedef TextureManager::TextureInfo TextureInfo; |
| namespace content { |
| TextureImageTransportSurface::Texture::Texture() |
| - : client_id(0), |
| - sent_to_client(false) { |
| + : service_id(0), |
| + identifier(0) { |
| } |
| TextureImageTransportSurface::Texture::~Texture() { |
| @@ -37,17 +39,12 @@ TextureImageTransportSurface::TextureImageTransportSurface( |
| GpuCommandBufferStub* stub, |
| const gfx::GLSurfaceHandle& handle) |
| : fbo_id_(0), |
| - front_(0), |
| stub_destroyed_(false), |
| backbuffer_suggested_allocation_(true), |
| frontbuffer_suggested_allocation_(true), |
| - frontbuffer_is_protected_(true), |
| - protection_state_id_(0), |
| handle_(handle), |
| - parent_stub_(NULL), |
| is_swap_buffers_pending_(false), |
| - did_unschedule_(false), |
| - did_flip_(false) { |
| + did_unschedule_(false) { |
| helper_.reset(new ImageTransportHelper(this, |
| manager, |
| stub, |
| @@ -60,39 +57,12 @@ TextureImageTransportSurface::~TextureImageTransportSurface() { |
| } |
| bool TextureImageTransportSurface::Initialize() { |
| - GpuChannelManager* manager = helper_->manager(); |
| - GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); |
| - if (!parent_channel) |
| - return false; |
| - |
| - parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id); |
| - if (!parent_stub_) |
| - return false; |
| + mailbox_manager_ = |
| + helper_->stub()->decoder()->GetContextGroup()->mailbox_manager(); |
| - parent_stub_->AddDestructionObserver(this); |
| - TextureManager* texture_manager = |
| - parent_stub_->decoder()->GetContextGroup()->texture_manager(); |
| - DCHECK(texture_manager); |
| - |
| - for (int i = 0; i < 2; ++i) { |
| - Texture& texture = textures_[i]; |
| - texture.client_id = handle_.parent_texture_id[i]; |
| - texture.info = texture_manager->GetTextureInfo(texture.client_id); |
| - if (!texture.info) |
| - return false; |
| - |
| - if (!texture.info->target()) |
| - texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D); |
| - texture_manager->SetParameter( |
| - texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| - texture_manager->SetParameter( |
| - texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| - texture_manager->SetParameter( |
| - texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| - texture_manager->SetParameter( |
| - texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| - } |
| + backbuffer_.identifier = 1; |
| + GpuChannelManager* manager = helper_->manager(); |
| surface_ = manager->GetDefaultOffscreenSurface(); |
| if (!surface_.get()) |
| return false; |
| @@ -100,17 +70,20 @@ bool TextureImageTransportSurface::Initialize() { |
| if (!helper_->Initialize()) |
| return false; |
| - const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| - if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) |
| - helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); |
| + GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); |
| + if (parent_channel) { |
| + const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| + if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) |
| + helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); |
| + } |
| return true; |
| } |
| void TextureImageTransportSurface::Destroy() { |
| - if (parent_stub_) { |
| - parent_stub_->decoder()->MakeCurrent(); |
| - ReleaseParentStub(); |
| + if (!stub_destroyed_) { |
| + GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
| + helper_->SendAcceleratedSurfaceRelease(params); |
| } |
| if (surface_.get()) |
| @@ -149,10 +122,19 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { |
| return true; |
| } |
| + if (!context_.get()) |
| + context_ = helper_->stub()->decoder()->GetGLContext(); |
| + |
| if (!fbo_id_) { |
| glGenFramebuffersEXT(1, &fbo_id_); |
| glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_); |
| - CreateBackTexture(gfx::Size(1, 1)); |
| + current_size_ = gfx::Size(1, 1); |
| + DCHECK(helper_->stub()); |
|
jonathan.backer
2012/11/20 21:21:11
Seems a little late for this. Probably would have
|
| + helper_->stub()->AddDestructionObserver(this); |
| + } |
| + |
| + if (!backbuffer_.service_id) { |
| + CreateBackTexture(); |
| #ifndef NDEBUG |
| GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| @@ -163,10 +145,7 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { |
| return false; |
| } |
| #endif |
| - DCHECK(helper_->stub()); |
| - helper_->stub()->AddDestructionObserver(this); |
| } |
| - |
| return true; |
| } |
| @@ -179,16 +158,11 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { |
| return; |
| backbuffer_suggested_allocation_ = allocation; |
| - if (!helper_->MakeCurrent()) |
| - return; |
| - |
| - if (backbuffer_suggested_allocation_) { |
| - DCHECK(!textures_[back()].info->service_id() || |
| - !textures_[back()].sent_to_client); |
| - CreateBackTexture(textures_[back()].size); |
| - } else { |
| - ReleaseTexture(back()); |
| - } |
| + // For |allocation| == true, we have to be careful as there might still be |
| + // a swap ACK pending. Either way, we will either retrieve the texture when |
|
piman
2012/11/29 04:31:11
note: with https://codereview.chromium.org/1131623
no sievers
2012/11/29 19:57:00
We could allocate it now if allocation == true, or
|
| + // the ACK is handled, or allocate a new one when being made current again. |
| + if (!backbuffer_suggested_allocation_ && helper_->MakeCurrent()) |
| + ReleaseBackBuffer(); |
| } |
| void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { |
| @@ -199,18 +173,9 @@ void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { |
| } |
| void TextureImageTransportSurface::AdjustFrontBufferAllocation() { |
| - if (!helper_->MakeCurrent()) |
| - return; |
| - |
| - if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && |
| - textures_[front()].info->service_id()) { |
| - ReleaseTexture(front()); |
| - if (textures_[front()].sent_to_client) { |
| - GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
| - params.identifier = textures_[front()].client_id; |
| - helper_->SendAcceleratedSurfaceRelease(params); |
| - textures_[front()].sent_to_client = false; |
| - } |
| + if (!frontbuffer_suggested_allocation_) { |
| + GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
| + helper_->SendAcceleratedSurfaceRelease(params); |
| } |
| } |
| @@ -227,50 +192,42 @@ void* TextureImageTransportSurface::GetConfig() { |
| } |
| void TextureImageTransportSurface::OnResize(gfx::Size size) { |
| - CreateBackTexture(size); |
| + current_size_ = size; |
| + CreateBackTexture(); |
| } |
| void TextureImageTransportSurface::OnWillDestroyStub( |
| GpuCommandBufferStub* stub) { |
| - if (stub == parent_stub_) { |
| - ReleaseParentStub(); |
| - helper_->SetPreemptByCounter(NULL); |
| - } else { |
| - DCHECK(stub == helper_->stub()); |
| - stub->RemoveDestructionObserver(this); |
| - |
| - // We are losing the stub owning us, this is our last chance to clean up the |
| - // resources we allocated in the stub's context. |
| - if (fbo_id_) { |
| - glDeleteFramebuffersEXT(1, &fbo_id_); |
| - CHECK_GL_ERROR(); |
| - fbo_id_ = 0; |
| - } |
| + DCHECK(stub == helper_->stub()); |
| + stub->RemoveDestructionObserver(this); |
| - stub_destroyed_ = true; |
| + // We are losing the stub owning us, this is our last chance to clean up the |
| + // resources we allocated in the stub's context. |
| + if (fbo_id_) { |
| + glDeleteFramebuffersEXT(1, &fbo_id_); |
| + CHECK_GL_ERROR(); |
| + fbo_id_ = 0; |
| } |
| + |
| + stub_destroyed_ = true; |
| } |
| bool TextureImageTransportSurface::SwapBuffers() { |
| DCHECK(backbuffer_suggested_allocation_); |
| - if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| + if (!frontbuffer_suggested_allocation_) |
| return true; |
| - if (!parent_stub_) { |
| - LOG(ERROR) << "SwapBuffers failed because no parent stub."; |
| - return false; |
| - } |
| glFlush(); |
| - front_ = back(); |
| - previous_damage_rect_ = gfx::Rect(textures_[front()].size); |
| + const uint64 identifier = backbuffer_.identifier; |
| + ProduceTexture(backbuffer_); |
| - DCHECK(textures_[front()].client_id != 0); |
| + // Do not allow destruction while we are still waiting for a swap ACK, |
| + // so we do not leak a texture in the mailbox. |
| + AddRef(); |
| GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| - params.surface_handle = textures_[front()].client_id; |
| - params.size = textures_[front()].size; |
| - params.protection_state_id = protection_state_id_; |
| - params.skip_ack = false; |
| + params.surface_handle = identifier; |
| + params.size = current_size_; |
| helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| DCHECK(!is_swap_buffers_pending_); |
| @@ -281,68 +238,31 @@ bool TextureImageTransportSurface::SwapBuffers() { |
| bool TextureImageTransportSurface::PostSubBuffer( |
| int x, int y, int width, int height) { |
| DCHECK(backbuffer_suggested_allocation_); |
| - DCHECK(textures_[back()].info->service_id()); |
| - if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| + DCHECK(backbuffer_.service_id); |
| + if (!frontbuffer_suggested_allocation_) |
| return true; |
| - // If we are recreating the frontbuffer with this swap, make sure we are |
| - // drawing a full frame. |
| - DCHECK(textures_[front()].info->service_id() || |
| - (!x && !y && gfx::Size(width, height) == textures_[back()].size)); |
| - if (!parent_stub_) { |
| - LOG(ERROR) << "PostSubBuffer failed because no parent stub."; |
| - return false; |
| - } |
| - |
| const gfx::Rect new_damage_rect(x, y, width, height); |
| + DCHECK(gfx::Rect(gfx::Point(), current_size_).Contains(new_damage_rect)); |
| // An empty damage rect is a successful no-op. |
| if (new_damage_rect.IsEmpty()) |
| return true; |
| - int back_texture_service_id = textures_[back()].info->service_id(); |
| - int front_texture_service_id = textures_[front()].info->service_id(); |
| - |
| - gfx::Size expected_size = textures_[back()].size; |
| - bool surfaces_same_size = textures_[front()].size == expected_size; |
| - |
| - if (surfaces_same_size) { |
| - std::vector<gfx::Rect> regions_to_copy; |
| - GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy); |
| - |
| - ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| - GL_COLOR_ATTACHMENT0, |
| - GL_TEXTURE_2D, |
| - front_texture_service_id, |
| - 0); |
| - ScopedTextureBinder texture_binder(back_texture_service_id); |
| - |
| - for (size_t i = 0; i < regions_to_copy.size(); ++i) { |
| - const gfx::Rect& region_to_copy = regions_to_copy[i]; |
| - if (!region_to_copy.IsEmpty()) { |
| - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(), |
| - region_to_copy.y(), region_to_copy.x(), region_to_copy.y(), |
| - region_to_copy.width(), region_to_copy.height()); |
| - } |
| - } |
| - } else if (!surfaces_same_size && did_flip_) { |
| - DCHECK(new_damage_rect == gfx::Rect(expected_size)); |
| - } |
| - |
| glFlush(); |
| - front_ = back(); |
| - previous_damage_rect_ = new_damage_rect; |
| + const uint64 identifier = backbuffer_.identifier; |
| + ProduceTexture(backbuffer_); |
| - DCHECK(textures_[front()].client_id); |
| + // Do not allow destruction while we are still waiting for a swap ACK, |
| + // so we do not leak a texture in the mailbox. |
| + AddRef(); |
| GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
| - params.surface_handle = textures_[front()].client_id; |
| - params.surface_size = textures_[front()].size; |
| + params.surface_handle = identifier; |
| + params.surface_size = current_size_; |
| params.x = x; |
| params.y = y; |
| params.width = width; |
| params.height = height; |
| - params.protection_state_id = protection_state_id_; |
| helper_->SendAcceleratedSurfacePostSubBuffer(params); |
| DCHECK(!is_swap_buffers_pending_); |
| @@ -359,7 +279,7 @@ std::string TextureImageTransportSurface::GetExtensions() { |
| } |
| gfx::Size TextureImageTransportSurface::GetSize() { |
| - gfx::Size size = textures_[back()].size; |
| + gfx::Size size = current_size_; |
| // OSMesa expects a non-zero size. |
| return gfx::Size(size.width() == 0 ? 1 : size.width(), |
| @@ -374,70 +294,56 @@ unsigned TextureImageTransportSurface::GetFormat() { |
| return surface_.get() ? surface_->GetFormat() : 0; |
| } |
| -void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( |
| - bool is_protected, uint32 protection_state_id) { |
| - protection_state_id_ = protection_state_id; |
| - if (frontbuffer_is_protected_ == is_protected) |
| - return; |
| - frontbuffer_is_protected_ = is_protected; |
| - AdjustFrontBufferAllocation(); |
| - |
| - // If surface is set to protected, and we haven't actually released it yet, |
| - // we can set the ui surface handle now just by sending a swap message. |
| - if (is_protected && textures_[front()].info->service_id() && |
| - textures_[front()].sent_to_client) { |
| - GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| - params.surface_handle = textures_[front()].client_id; |
| - params.size = textures_[front()].size; |
| - params.protection_state_id = protection_state_id_; |
| - params.skip_ack = true; |
| - helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| - } |
| -} |
| - |
| -void TextureImageTransportSurface::OnBufferPresented(bool presented, |
| +void TextureImageTransportSurface::OnBufferPresented(uint64 surface_handle, |
| uint32 sync_point) { |
| if (sync_point == 0) { |
| - BufferPresentedImpl(presented); |
| + BufferPresentedImpl(surface_handle); |
| } else { |
| helper_->manager()->sync_point_manager()->AddSyncPointCallback( |
| sync_point, |
| base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, |
| - this->AsWeakPtr(), |
| - presented)); |
| + this, |
| + surface_handle)); |
| } |
| -} |
| -void TextureImageTransportSurface::BufferPresentedImpl(bool presented) { |
| - DCHECK(is_swap_buffers_pending_); |
| - is_swap_buffers_pending_ = false; |
| + // Careful, we might get deleted now if we were only waiting for |
| + // a final swap ACK. |
| + Release(); |
|
jonathan.backer
2012/11/20 21:21:11
Hmm... do we want |BufferPresentedImpl| to do the
piman
2012/11/29 04:31:11
This looks fine, in the first case (sync_point==0)
|
| +} |
| - if (presented) { |
| - // If we had not flipped, the two frame damage tracking is inconsistent. |
| - // So conservatively take the whole frame. |
| - if (!did_flip_) |
| - previous_damage_rect_ = gfx::Rect(textures_[front()].size); |
| +void TextureImageTransportSurface::BufferPresentedImpl(uint64 surface_handle) { |
| + DCHECK(!backbuffer_.service_id); |
| + if (surface_handle) { |
| + backbuffer_.identifier = surface_handle; |
|
piman
2012/11/30 03:54:32
nit: DCHECK it's 1 or 2?
|
| + ConsumeTexture(backbuffer_); |
| } else { |
| - front_ = back(); |
| - previous_damage_rect_ = gfx::Rect(0, 0, 0, 0); |
| + // We didn't get back a texture, so allocate 'the other' buffer. |
| + backbuffer_.identifier = (backbuffer_.identifier == 1) ? 2 : 1; |
| + } |
| + |
| + if (stub_destroyed_ && backbuffer_.service_id) { |
| + // TODO(sievers): Remove this after changes to the mailbox to take ownership |
| + // of the service ids. |
| + DCHECK(context_.get() && surface_.get()); |
| + if (context_->MakeCurrent(surface_.get())) |
| + glDeleteTextures(1, &backbuffer_.service_id); |
|
piman
2012/11/30 03:54:32
nit: indent
|
| + |
| + return; |
| } |
| - did_flip_ = presented; |
| + DCHECK(is_swap_buffers_pending_); |
| + is_swap_buffers_pending_ = false; |
| // We're relying on the fact that the parent context is |
| // finished with it's context when it inserts the sync point that |
| // triggers this callback. |
| if (helper_->MakeCurrent()) { |
| - if (textures_[front()].size != textures_[back()].size || |
| - !textures_[back()].info->service_id() || |
| - !textures_[back()].sent_to_client) { |
| - // We may get an ACK from a stale swap just to reschedule. In that case, |
| - // we may not have a backbuffer suggestion and should not recreate one. |
| - if (backbuffer_suggested_allocation_) |
| - CreateBackTexture(textures_[front()].size); |
| - } else { |
| + if (!backbuffer_suggested_allocation_) |
| + ReleaseBackBuffer(); |
| + else if (backbuffer_.size != current_size_ || !backbuffer_.service_id) |
| + CreateBackTexture(); |
|
piman
2012/11/30 03:54:32
If we're going to recreate the backbuffer lazily i
|
| + else |
| AttachBackTextureToFBO(); |
| - } |
| } |
| // Even if MakeCurrent fails, schedule anyway, to trigger the lost context |
| @@ -452,94 +358,70 @@ void TextureImageTransportSurface::OnResizeViewACK() { |
| NOTREACHED(); |
| } |
| -void TextureImageTransportSurface::ReleaseTexture(int id) { |
| - if (!parent_stub_) |
| - return; |
| - Texture& texture = textures_[id]; |
| - TextureInfo* info = texture.info; |
| - DCHECK(info); |
| - |
| - GLuint service_id = info->service_id(); |
| - if (!service_id) |
| +void TextureImageTransportSurface::ReleaseBackBuffer() { |
| + if (!backbuffer_.service_id) |
| return; |
| - info->SetServiceId(0); |
| - { |
| - ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| - glDeleteTextures(1, &service_id); |
| - } |
| + glDeleteTextures(1, &backbuffer_.service_id); |
| + backbuffer_.service_id = 0; |
| glFlush(); |
| CHECK_GL_ERROR(); |
| } |
| -void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
| - if (!parent_stub_) |
| +void TextureImageTransportSurface::CreateBackTexture() { |
| + // If |is_swap_buffers_pending| we are waiting for our backbuffer |
| + // in the mailbox, so we shouldn't be reallocating it now. |
| + // The deferred scheduling logic guarantees that the context would |
| + // only be made current here for non-drawing GL commands, so it's |
| + // safe to bail out. |
| + if (is_swap_buffers_pending_) |
|
jonathan.backer
2012/11/20 21:21:11
I'm confused (you may have addressed this before),
piman
2012/11/29 04:31:11
I think with https://codereview.chromium.org/11316
no sievers
2012/11/29 19:57:00
We could still get non-drawing GL commands, right?
piman
2012/11/30 03:54:32
So, yes, we may run some GL commands, which will c
|
| return; |
| - Texture& texture = textures_[back()]; |
| - TextureInfo* info = texture.info; |
| - DCHECK(info); |
| - |
| - GLuint service_id = info->service_id(); |
| - if (service_id && texture.size == size && texture.sent_to_client) |
| + if (backbuffer_.service_id && backbuffer_.size == current_size_) |
| return; |
| - if (!service_id) { |
| - glGenTextures(1, &service_id); |
| - info->SetServiceId(service_id); |
| + DCHECK(!backbuffer_.service_id || mailbox_names_.count( |
| + backbuffer_.identifier)); |
|
jonathan.backer
2012/11/20 21:21:11
nit: indentation
|
| + if (!backbuffer_.service_id) { |
| + MailboxName new_mailbox_name; |
| + mailbox_manager_->GenerateMailboxName(&new_mailbox_name); |
| + mailbox_names_[backbuffer_.identifier] = new_mailbox_name; |
|
piman
2012/11/30 03:54:32
Should we check that the mailbox_names_ slot is em
no sievers
2012/12/01 00:58:38
We do replace the entry though when we reallocate
piman
2012/12/03 21:08:43
Why? resize shouldn't cause us to gen a new textur
no sievers
2012/12/03 23:20:38
Done.
|
| + glGenTextures(1, &backbuffer_.service_id); |
| } |
| - if (size != texture.size) { |
| - texture.size = size; |
| - TextureManager* texture_manager = |
| - parent_stub_->decoder()->GetContextGroup()->texture_manager(); |
| - texture_manager->SetLevelInfo( |
| - info, |
| - GL_TEXTURE_2D, |
| - 0, |
| - GL_RGBA, |
| - size.width(), |
| - size.height(), |
| - 1, |
| - 0, |
| - GL_RGBA, |
| - GL_UNSIGNED_BYTE, |
| - true); |
| - } |
| + backbuffer_.size = current_size_; |
| { |
| - ScopedTextureBinder texture_binder(service_id); |
| + ScopedTextureBinder texture_binder(backbuffer_.service_id); |
| glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
| - size.width(), size.height(), 0, |
| + current_size_.width(), current_size_.height(), 0, |
| GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| CHECK_GL_ERROR(); |
| } |
| AttachBackTextureToFBO(); |
| + const MailboxName& mailbox_name = mailbox_names_[backbuffer_.identifier]; |
| + |
| GpuHostMsg_AcceleratedSurfaceNew_Params params; |
| - params.width = size.width(); |
| - params.height = size.height(); |
| - params.surface_handle = texture.client_id; |
| + params.width = current_size_.width(); |
| + params.height = current_size_.height(); |
| + params.surface_handle = backbuffer_.identifier; |
| + params.mailbox_name.append((char*)&mailbox_name, sizeof(mailbox_name)); |
|
piman
2012/11/30 03:54:32
nit: no c-style cast (use reinterpret_cast).
|
| helper_->SendAcceleratedSurfaceNew(params); |
| - texture.sent_to_client = true; |
| } |
| void TextureImageTransportSurface::AttachBackTextureToFBO() { |
| - if (!parent_stub_) |
| - return; |
| - TextureInfo* info = textures_[back()].info; |
| - DCHECK(info); |
| - |
| + DCHECK(backbuffer_.service_id); |
| ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| GL_COLOR_ATTACHMENT0, |
| GL_TEXTURE_2D, |
| - info->service_id(), |
| + backbuffer_.service_id, |
| 0); |
| glFlush(); |
| CHECK_GL_ERROR(); |
| @@ -547,24 +429,49 @@ void TextureImageTransportSurface::AttachBackTextureToFBO() { |
| #ifndef NDEBUG |
| GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) { |
| - DLOG(ERROR) << "Framebuffer incomplete."; |
| + DLOG(FATAL) << "Framebuffer incomplete: " << status; |
| } |
| #endif |
| } |
| -void TextureImageTransportSurface::ReleaseParentStub() { |
| - DCHECK(parent_stub_); |
| - parent_stub_->RemoveDestructionObserver(this); |
| - for (int i = 0; i < 2; ++i) { |
| - Texture& texture = textures_[i]; |
| - texture.info = NULL; |
| - if (!texture.sent_to_client) |
| - continue; |
| - GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
| - params.identifier = texture.client_id; |
| - helper_->SendAcceleratedSurfaceRelease(params); |
| +void TextureImageTransportSurface::ConsumeTexture(Texture& texture) { |
| + DCHECK(!texture.service_id); |
| + DCHECK(texture.identifier == 1 || texture.identifier == 2); |
| + |
| + scoped_ptr<TextureDefinition> definition(mailbox_manager_->ConsumeTexture( |
| + GL_TEXTURE_2D, mailbox_names_[texture.identifier])); |
| + if (definition.get()) { |
| + texture.service_id = definition->ReleaseServiceId(); |
| + texture.size = gfx::Size(definition->level_infos()[0][0].width, |
| + definition->level_infos()[0][0].height); |
| } |
| - parent_stub_ = NULL; |
| +} |
| + |
| +void TextureImageTransportSurface::ProduceTexture(Texture& texture) { |
| + DCHECK(texture.service_id); |
| + DCHECK(texture.identifier == 1 || texture.identifier == 2); |
| + TextureManager* texture_manager = |
| + helper_->stub()->decoder()->GetContextGroup()->texture_manager(); |
| + DCHECK(texture.size.width() > 0 && texture.size.height() > 0); |
| + TextureDefinition::LevelInfo info( |
| + GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1, |
| + 0, GL_RGBA, GL_UNSIGNED_BYTE, true); |
| + |
| + TextureDefinition::LevelInfos level_infos; |
| + level_infos.resize(1); |
| + level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D)); |
| + level_infos[0][0] = info; |
| + scoped_ptr<TextureDefinition> definition(new TextureDefinition( |
| + GL_TEXTURE_2D, |
| + texture.service_id, |
| + true, |
| + level_infos)); |
| + mailbox_manager_->ProduceTexture( |
| + GL_TEXTURE_2D, |
| + mailbox_names_[texture.identifier], |
| + definition.release(), |
| + helper_->stub()->decoder()->GetContextGroup()->texture_manager()); |
| + texture.service_id = 0; |
| } |
| } // namespace content |