Chromium Code Reviews| Index: content/browser/compositor/buffer_queue.cc |
| diff --git a/content/browser/compositor/buffer_queue.cc b/content/browser/compositor/buffer_queue.cc |
| index 8809972ed359cdc55d314acbcd77ddca60654b85..f73dbf6a5c41020a6441da883a91b2729e1d21f1 100644 |
| --- a/content/browser/compositor/buffer_queue.cc |
| +++ b/content/browser/compositor/buffer_queue.cc |
| @@ -5,17 +5,22 @@ |
| #include "content/browser/compositor/buffer_queue.h" |
| #include "content/common/gpu/client/context_provider_command_buffer.h" |
| +#include "content/common/gpu/client/gl_helper.h" |
| #include "gpu/GLES2/gl2extchromium.h" |
| #include "gpu/command_buffer/client/gles2_interface.h" |
| +#include "third_party/skia/include/core/SkRect.h" |
| +#include "third_party/skia/include/core/SkRegion.h" |
| namespace content { |
| BufferQueue::BufferQueue(scoped_refptr<cc::ContextProvider> context_provider, |
| + GLHelper* gl_helper, |
| unsigned int internalformat) |
| : context_provider_(context_provider), |
| fbo_(0), |
| allocated_count_(0), |
| - internalformat_(internalformat) { |
| + internalformat_(internalformat), |
| + gl_helper_(gl_helper) { |
| } |
| BufferQueue::~BufferQueue() { |
| @@ -46,8 +51,57 @@ void BufferQueue::BindFramebuffer() { |
| } |
| } |
| -void BufferQueue::SwapBuffers() { |
| - in_flight_surfaces_.push(current_surface_); |
| +void BufferQueue::CopyBufferDamage(int texture, |
| + int source_texture, |
| + const gfx::Rect& exclude_rect, |
| + const gfx::Rect& copy_rect) { |
| + gl_helper_->CopySubBufferDamage( |
| + texture, |
| + source_texture, |
| + SkRegion(SkIRect::MakeXYWH(exclude_rect.x(), |
| + exclude_rect.y(), |
| + exclude_rect.width(), |
| + exclude_rect.height())), |
| + SkRegion(SkIRect::MakeXYWH(copy_rect.x(), |
| + copy_rect.y(), |
| + copy_rect.width(), |
| + copy_rect.height()))); |
| +} |
| + |
| +void BufferQueue::SwapBuffers(const gfx::Rect& damage) { |
| + if (damage != gfx::Rect(size_)) { |
| + // We must have a frame available to copy from. |
| + DCHECK(!in_flight_surfaces_.empty()); |
| + |
| + if (!damage.Contains(current_surface_.damage)) { |
|
alexst (slow to review)
2014/09/18 15:39:15
Contract on CopyBufferDamage says "Copies all pixe
achaulk
2014/09/18 16:45:02
Sure, but we need it anyway for the below set
|
| + CopyBufferDamage(current_surface_.texture, |
| + in_flight_surfaces_.back().texture, |
| + damage, |
| + current_surface_.damage); |
| + // Because we copied everything except |damage| to this texture, |
| + // the cumulative damage for this frame is only |damage| now. |
| + in_flight_surfaces_.back().damage = damage; |
|
alexst (slow to review)
2014/09/18 15:39:15
I think this is redundant with the for loop below
achaulk
2014/09/18 16:45:02
Not entirely, the important bit is that it any exi
|
| + } |
| + |
| + // Compute cumulative damage for all frames. |
| + for (size_t i = 0; i < available_surfaces_.size(); i++) |
|
alexst (slow to review)
2014/09/18 15:39:15
Can you break this into a separate function SetDam
achaulk
2014/09/18 16:45:02
Sure
|
| + available_surfaces_[i].damage.Union(damage); |
| + for (std::deque<AllocatedSurface>::iterator it = |
| + in_flight_surfaces_.begin(); |
| + it != in_flight_surfaces_.end(); |
| + ++it) |
| + it->damage.Union(damage); |
| + } else { |
| + for (size_t i = 0; i < available_surfaces_.size(); i++) |
| + available_surfaces_[i].damage = damage; |
| + for (std::deque<AllocatedSurface>::iterator it = |
| + in_flight_surfaces_.begin(); |
| + it != in_flight_surfaces_.end(); |
| + ++it) |
| + it->damage = damage; |
| + } |
| + current_surface_.damage = gfx::Rect(); |
| + in_flight_surfaces_.push_back(current_surface_); |
| current_surface_.texture = 0; |
| current_surface_.image = 0; |
| } |
| @@ -70,7 +124,7 @@ void BufferQueue::Reshape(const gfx::Size& size, float scale_factor) { |
| void BufferQueue::PageFlipComplete() { |
| if (in_flight_surfaces_.size() > 1) { |
| available_surfaces_.push_back(in_flight_surfaces_.front()); |
| - in_flight_surfaces_.pop(); |
| + in_flight_surfaces_.pop_front(); |
| } |
| } |
| @@ -78,7 +132,7 @@ void BufferQueue::FreeAllSurfaces() { |
| FreeSurface(¤t_surface_); |
| while (!in_flight_surfaces_.empty()) { |
| FreeSurface(&in_flight_surfaces_.front()); |
| - in_flight_surfaces_.pop(); |
| + in_flight_surfaces_.pop_front(); |
| } |
| for (size_t i = 0; i < available_surfaces_.size(); i++) |
| FreeSurface(&available_surfaces_[i]); |
| @@ -100,9 +154,9 @@ void BufferQueue::FreeSurface(AllocatedSurface* surface) { |
| BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() { |
| if (!available_surfaces_.empty()) { |
| - AllocatedSurface id = available_surfaces_.back(); |
| + AllocatedSurface surface = available_surfaces_.back(); |
| available_surfaces_.pop_back(); |
| - return id; |
| + return surface; |
| } |
| unsigned int texture = 0; |
| @@ -122,7 +176,7 @@ BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() { |
| allocated_count_++; |
| gl->BindTexture(GL_TEXTURE_2D, texture); |
| gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, id); |
| - return AllocatedSurface(texture, id); |
| + return AllocatedSurface(texture, id, gfx::Rect(size_)); |
| } |
| } // namespace content |