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 ec81bbc75f115575e5c56a0b4d12a54338c69e51..5abeb823794e37ce2ef188f35c177b896422b5ab 100644 |
| --- a/content/common/gpu/texture_image_transport_surface.cc |
| +++ b/content/common/gpu/texture_image_transport_surface.cc |
| @@ -69,6 +69,8 @@ TextureImageTransportSurface::TextureImageTransportSurface( |
| stub_destroyed_(false), |
| backbuffer_suggested_allocation_(true), |
| frontbuffer_suggested_allocation_(true), |
| + frontbuffer_is_protected_(true), |
| + protection_state_id_(0), |
| handle_(handle), |
| parent_stub_(NULL) { |
| helper_.reset(new ImageTransportHelper(this, |
| @@ -182,16 +184,36 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { |
| if (!helper_->MakeCurrent()) |
| return; |
| - if (backbuffer_suggested_allocation_) |
| + if (backbuffer_suggested_allocation_) { |
| + DCHECK(!textures_[back()].info->service_id() || |
| + !textures_[back()].sent_to_client); |
| CreateBackTexture(textures_[back()].size); |
| - else |
| - ReleaseBackTexture(); |
| + } else { |
| + ReleaseTexture(back()); |
| + } |
| } |
| void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { |
| if (frontbuffer_suggested_allocation_ == allocation) |
| return; |
| frontbuffer_suggested_allocation_ = allocation; |
| + AdjustFrontBufferAllocation(); |
| +} |
| + |
| +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; |
| + } |
| + } |
| } |
| void* TextureImageTransportSurface::GetShareHandle() { |
| @@ -232,7 +254,7 @@ void TextureImageTransportSurface::OnWillDestroyStub( |
| bool TextureImageTransportSurface::SwapBuffers() { |
| DCHECK(backbuffer_suggested_allocation_); |
| - if (!frontbuffer_suggested_allocation_) |
| + if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| return true; |
| if (!parent_stub_) { |
| LOG(ERROR) << "SwapBuffers failed because no parent stub."; |
| @@ -241,12 +263,16 @@ bool TextureImageTransportSurface::SwapBuffers() { |
| glFlush(); |
| front_ = back(); |
| - previous_damage_rect_ = gfx::Rect(textures_[front_].size); |
| + previous_damage_rect_ = gfx::Rect(textures_[front()].size); |
| - DCHECK(textures_[front_].client_id != 0); |
| + DCHECK(textures_[front()].client_id != 0); |
| GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| - params.surface_handle = textures_[front_].client_id; |
| + params.surface_handle = textures_[front()].client_id; |
| +#if defined(USE_AURA) |
| + params.protection_state_id = protection_state_id_; |
| + params.require_ack = true; |
| +#endif |
| helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| helper_->SetScheduled(false); |
| return true; |
| @@ -255,32 +281,30 @@ bool TextureImageTransportSurface::SwapBuffers() { |
| bool TextureImageTransportSurface::PostSubBuffer( |
| int x, int y, int width, int height) { |
| DCHECK(backbuffer_suggested_allocation_); |
| - if (!frontbuffer_suggested_allocation_) |
| + DCHECK(textures_[back()].info->service_id()); |
| + if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
| 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() || |
| + 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; |
| } |
| - DCHECK(textures_[back()].info); |
| - int back_texture_service_id = textures_[back()].info->service_id(); |
| - |
| - DCHECK(textures_[front_].info); |
| - 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; |
| - |
| const gfx::Rect new_damage_rect(x, y, width, height); |
| // 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); |
| @@ -307,17 +331,21 @@ bool TextureImageTransportSurface::PostSubBuffer( |
| glFlush(); |
| front_ = back(); |
| + previous_damage_rect_ = new_damage_rect; |
| + |
| + DCHECK(textures_[front()].client_id); |
| GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
| - params.surface_handle = textures_[front_].client_id; |
| + params.surface_handle = textures_[front()].client_id; |
| params.x = x; |
| params.y = y; |
| params.width = width; |
| params.height = height; |
| +#if defined(USE_AURA) |
|
piman
2012/06/12 23:05:12
nit: somehow it feels wrong to have a #ifdef USE_A
|
| + params.protection_state_id = protection_state_id_; |
| +#endif |
| helper_->SendAcceleratedSurfacePostSubBuffer(params); |
| helper_->SetScheduled(false); |
| - |
| - previous_damage_rect_ = new_damage_rect; |
| return true; |
| } |
| @@ -342,10 +370,37 @@ void TextureImageTransportSurface::OnNewSurfaceACK( |
| uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) { |
| } |
| +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; |
| +#if defined(USE_AURA) |
| + params.protection_state_id = protection_state_id_; |
| + params.require_ack = false; |
| +#endif |
| + helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| + } |
| +} |
| + |
| void TextureImageTransportSurface::OnBuffersSwappedACK() { |
| if (helper_->MakeCurrent()) { |
| - if (textures_[front_].size != textures_[back()].size) { |
| - CreateBackTexture(textures_[front_].size); |
| + 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 { |
| AttachBackTextureToFBO(); |
| } |
| @@ -364,10 +419,11 @@ void TextureImageTransportSurface::OnResizeViewACK() { |
| NOTREACHED(); |
| } |
| -void TextureImageTransportSurface::ReleaseBackTexture() { |
| +void TextureImageTransportSurface::ReleaseTexture(int id) { |
| if (!parent_stub_) |
| return; |
| - TextureInfo* info = textures_[back()].info; |
| + Texture& texture = textures_[id]; |
| + TextureInfo* info = texture.info; |
| DCHECK(info); |
| GLuint service_id = info->service_id(); |
| @@ -392,7 +448,7 @@ void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
| GLuint service_id = info->service_id(); |
| - if (service_id && texture.size == size) |
| + if (service_id && texture.size == size && texture.sent_to_client) |
| return; |
| if (!service_id) { |
| @@ -443,13 +499,14 @@ void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
| void TextureImageTransportSurface::AttachBackTextureToFBO() { |
| if (!parent_stub_) |
| return; |
| - DCHECK(textures_[back()].info); |
| + TextureInfo* info = textures_[back()].info; |
| + DCHECK(info); |
| ScopedFrameBufferBinder fbo_binder(fbo_id_); |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| GL_COLOR_ATTACHMENT0, |
| GL_TEXTURE_2D, |
| - textures_[back()].info->service_id(), |
| + info->service_id(), |
| 0); |
| glFlush(); |
| CHECK_GL_ERROR(); |