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 40f76caccf1dd4283d468532408ad59398eba7c1..d92ad27eb5b5f44209ff75985e81b7c8532358f4 100644 |
--- a/content/common/gpu/texture_image_transport_surface.cc |
+++ b/content/common/gpu/texture_image_transport_surface.cc |
@@ -190,6 +190,7 @@ void TextureImageTransportSurface::OnWillDestroyStub( |
bool TextureImageTransportSurface::SwapBuffers() { |
glFlush(); |
front_ = back(); |
+ previous_damage_rect_ = gfx::Rect(textures_[front_].size); |
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
params.surface_handle = textures_[front_].client_id; |
@@ -200,15 +201,68 @@ bool TextureImageTransportSurface::SwapBuffers() { |
bool TextureImageTransportSurface::PostSubBuffer( |
int x, int y, int width, int height) { |
- // TODO(piman): implement this, similarly to EGLImageTransportSurface. |
- NOTREACHED(); |
- return false; |
+ if (!parent_stub_.get()) |
+ return false; |
+ |
+ TextureInfo* info = GetParentInfo(textures_[back()].client_id); |
+ if (!info) |
+ return false; |
+ int back_texture_service_id = info->service_id(); |
+ |
+ info = GetParentInfo(textures_[front_].client_id); |
+ if (!info) |
+ return false; |
+ int front_texture_service_id = 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); |
+ 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 { |
+ DCHECK(new_damage_rect == gfx::Rect(expected_size)); |
+ } |
+ |
+ glFlush(); |
+ front_ = back(); |
+ |
+ GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
+ 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; |
} |
std::string TextureImageTransportSurface::GetExtensions() { |
std::string extensions = gfx::GLSurface::GetExtensions(); |
extensions += extensions.empty() ? "" : " "; |
- extensions += "GL_CHROMIUM_front_buffer_cached"; |
+ extensions += "GL_CHROMIUM_front_buffer_cached "; |
+ extensions += "GL_CHROMIUM_post_sub_buffer"; |
return extensions; |
} |
@@ -240,7 +294,7 @@ void TextureImageTransportSurface::OnBuffersSwappedACK() { |
} |
void TextureImageTransportSurface::OnPostSubBufferACK() { |
- NOTREACHED(); |
+ OnBuffersSwappedACK(); |
} |
void TextureImageTransportSurface::OnResizeViewACK() { |