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 |