| 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 7e221139c65d7c862a8636f36d170df31df04549..c5fb0aaae3a0279f24061ac0e5c2c292d19f11e5 100644
|
| --- a/content/common/gpu/texture_image_transport_surface.cc
|
| +++ b/content/common/gpu/texture_image_transport_surface.cc
|
| @@ -67,6 +67,10 @@ TextureImageTransportSurface::TextureImageTransportSurface(
|
| stub_destroyed_(false),
|
| backbuffer_suggested_allocation_(true),
|
| frontbuffer_suggested_allocation_(true),
|
| + frontbuffer_is_protected_(true),
|
| + ui_may_not_have_frontbuffer_handle_(false),
|
| + current_valid_release_front_request_id_(0),
|
| + next_unique_release_front_request_id_(0),
|
| parent_stub_(NULL) {
|
| GpuChannel* parent_channel = manager->LookupChannel(handle.parent_client_id);
|
| DCHECK(parent_channel);
|
| @@ -168,13 +172,25 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
|
| if (backbuffer_suggested_allocation_)
|
| CreateBackTexture(textures_[back()].size);
|
| else
|
| - ReleaseBackTexture();
|
| + ReleaseTexture(back());
|
| }
|
|
|
| void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
|
| if (frontbuffer_suggested_allocation_ == allocation)
|
| return;
|
| frontbuffer_suggested_allocation_ = allocation;
|
| + AdjustFrontBufferAllocation(0);
|
| +}
|
| +
|
| +void TextureImageTransportSurface::AdjustFrontBufferAllocation(
|
| + int retry_count) {
|
| + if (!helper_->MakeCurrent())
|
| + return;
|
| +
|
| + if (!frontbuffer_suggested_allocation_ &&
|
| + textures_[front()].info->service_id() &&
|
| + !frontbuffer_is_protected_)
|
| + RequestReleaseFrontTexture(retry_count);
|
| }
|
|
|
| void* TextureImageTransportSurface::GetShareHandle() {
|
| @@ -210,6 +226,7 @@ void TextureImageTransportSurface::OnWillDestroyStub(
|
| }
|
|
|
| bool TextureImageTransportSurface::SwapBuffers() {
|
| + current_valid_release_front_request_id_ = 0;
|
| DCHECK(backbuffer_suggested_allocation_);
|
| if (!frontbuffer_suggested_allocation_)
|
| return true;
|
| @@ -220,12 +237,12 @@ 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;
|
| helper_->SendAcceleratedSurfaceBuffersSwapped(params);
|
| helper_->SetScheduled(false);
|
| return true;
|
| @@ -233,6 +250,7 @@ bool TextureImageTransportSurface::SwapBuffers() {
|
|
|
| bool TextureImageTransportSurface::PostSubBuffer(
|
| int x, int y, int width, int height) {
|
| + current_valid_release_front_request_id_ = 0;
|
| DCHECK(backbuffer_suggested_allocation_);
|
| if (!frontbuffer_suggested_allocation_)
|
| return true;
|
| @@ -245,21 +263,18 @@ bool TextureImageTransportSurface::PostSubBuffer(
|
| 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);
|
| @@ -286,17 +301,18 @@ bool TextureImageTransportSurface::PostSubBuffer(
|
|
|
| glFlush();
|
| front_ = back();
|
| + previous_damage_rect_ = new_damage_rect;
|
| +
|
| + DCHECK(textures_[front()].client_id != 0);
|
|
|
| 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;
|
| helper_->SendAcceleratedSurfacePostSubBuffer(params);
|
| helper_->SetScheduled(false);
|
| -
|
| - previous_damage_rect_ = new_damage_rect;
|
| return true;
|
| }
|
|
|
| @@ -321,10 +337,42 @@ void TextureImageTransportSurface::OnNewSurfaceACK(
|
| uint64 surface_handle, TransportDIB::Handle /*shm_handle*/) {
|
| }
|
|
|
| +void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
|
| + bool is_protected) {
|
| + if (frontbuffer_is_protected_ == is_protected)
|
| + return;
|
| + frontbuffer_is_protected_ = is_protected;
|
| + AdjustFrontBufferAllocation(0);
|
| +}
|
| +
|
| +void TextureImageTransportSurface::OnRequestReleaseFrontACK(
|
| + int request_id, int retry_count, bool was_released) {
|
| + if (!was_released) {
|
| + // If the browser ignored out request, but the request id is still valid,
|
| + // call AdjustFrontBufferAllocation, which will send another request only if
|
| + // it still makes sense to do so. This can happen with visibility ABA
|
| + // transitions.
|
| + if (request_id == current_valid_release_front_request_id_ &&
|
| + retry_count < kMaxRequestReleaseFrontRetries)
|
| + AdjustFrontBufferAllocation(retry_count + 1);
|
| + return;
|
| + }
|
| + if (frontbuffer_suggested_allocation_ || frontbuffer_is_protected_ ||
|
| + request_id != current_valid_release_front_request_id_)
|
| + return;
|
| + Texture& texture = textures_[front()];
|
| + texture.sent_to_client = false;
|
| + ReleaseTexture(front());
|
| +}
|
| +
|
| 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 ||
|
| + ui_may_not_have_frontbuffer_handle_) {
|
| + CreateBackTexture(textures_[front()].size);
|
| + ui_may_not_have_frontbuffer_handle_ = false;
|
| } else {
|
| AttachBackTextureToFBO();
|
| }
|
| @@ -343,10 +391,30 @@ void TextureImageTransportSurface::OnResizeViewACK() {
|
| NOTREACHED();
|
| }
|
|
|
| -void TextureImageTransportSurface::ReleaseBackTexture() {
|
| +void TextureImageTransportSurface::RequestReleaseFrontTexture(int retry_count) {
|
| + Texture& texture = textures_[front()];
|
| + DCHECK(texture.info);
|
| + DCHECK(texture.info->service_id());
|
| + if (!texture.sent_to_client) {
|
| + ReleaseTexture(front());
|
| + return;
|
| + }
|
| + if (!retry_count)
|
| + current_valid_release_front_request_id_ =
|
| + ++next_unique_release_front_request_id_;
|
| + GpuHostMsg_AcceleratedSurfaceRequestReleaseFront_Params params;
|
| + params.identifier = texture.client_id;
|
| + params.request_id = current_valid_release_front_request_id_;
|
| + params.retry_count = retry_count;
|
| + helper_->SendAcceleratedSurfaceRequestReleaseFront(params);
|
| + ui_may_not_have_frontbuffer_handle_ = true;
|
| +}
|
| +
|
| +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();
|
| @@ -371,7 +439,8 @@ 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 &&
|
| + !ui_may_not_have_frontbuffer_handle_ && texture.sent_to_client)
|
| return;
|
|
|
| if (!service_id) {
|
| @@ -422,13 +491,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();
|
|
|