Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1021)

Unified Diff: content/renderer/gpu/compositor_software_output_device.cc

Issue 15001027: [Aura] Added Support for rendering software compositor frames as cc::TextureLayers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Passed(&foo) instead for Passed(foo.Pass()). Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/gpu/compositor_software_output_device.h ('k') | gpu/command_buffer/common/mailbox.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/gpu/compositor_software_output_device.cc
diff --git a/content/renderer/gpu/compositor_software_output_device.cc b/content/renderer/gpu/compositor_software_output_device.cc
index cd22bed45787b9ac38a7a8bb3d3c1f623af62820..23710ab0bde870ea33da2872a8f30ddae97d8cc8 100644
--- a/content/renderer/gpu/compositor_software_output_device.cc
+++ b/content/renderer/gpu/compositor_software_output_device.cc
@@ -10,27 +10,56 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/core/SkRegion.h"
#include "ui/gfx/skia_util.h"
-#include "ui/surface/transport_dib.h"
namespace content {
-CompositorSoftwareOutputDevice::DIB::DIB(size_t size) {
- RenderProcess* render_process = RenderProcess::current();
- dib_ = render_process->CreateTransportDIB(size);
- CHECK(dib_);
- bool success = dib_->Map();
- CHECK(success);
+CompositorSoftwareOutputDevice::Buffer::Buffer(
+ unsigned id, scoped_ptr<base::SharedMemory> mem)
+ : id_(id),
+ mem_(mem.Pass()),
+ free_(true),
+ parent_(NULL) {
+}
+
+CompositorSoftwareOutputDevice::Buffer::~Buffer() {
}
-CompositorSoftwareOutputDevice::DIB::~DIB() {
- RenderProcess* render_process = RenderProcess::current();
- render_process->FreeTransportDIB(dib_);
+void CompositorSoftwareOutputDevice::Buffer::SetParent(
+ Buffer* parent, const gfx::Rect& damage) {
+ parent_ = parent;
+ damage_ = damage;
+}
+
+bool CompositorSoftwareOutputDevice::Buffer::FindDamageDifferenceFrom(
+ Buffer* buffer, SkRegion* result) const {
+ if (!buffer)
+ return false;
+
+ if (buffer == this) {
+ *result = SkRegion();
+ return true;
+ }
+
+ SkRegion damage;
+ const Buffer* current = this;
+ while (current->parent_) {
+ damage.op(RectToSkIRect(current->damage_), SkRegion::kUnion_Op);
+ if (current->parent_ == buffer) {
+ *result = damage;
+ return true;
+ }
+ current = current->parent_;
+ }
+
+ return false;
}
CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
- : front_buffer_(-1),
- num_free_buffers_(0) {
+ : current_index_(-1),
+ next_buffer_id_(1),
+ render_thread_(RenderThread::Get()) {
DetachFromThread();
}
@@ -38,10 +67,34 @@ CompositorSoftwareOutputDevice::~CompositorSoftwareOutputDevice() {
DCHECK(CalledOnValidThread());
}
-CompositorSoftwareOutputDevice::DIB*
-CompositorSoftwareOutputDevice::CreateDIB() {
- const size_t size = 4 * viewport_size_.GetArea();
- return new DIB(size);
+unsigned CompositorSoftwareOutputDevice::GetNextId() {
+ unsigned id = next_buffer_id_++;
+ // Zero is reserved to label invalid frame id.
+ if (id == 0)
+ id = next_buffer_id_++;
+ return id;
+}
+
+CompositorSoftwareOutputDevice::Buffer*
+CompositorSoftwareOutputDevice::CreateBuffer() {
+ const size_t size = 4 * viewport_size_.GetArea();
+ scoped_ptr<base::SharedMemory> mem =
+ render_thread_->HostAllocateSharedMemoryBuffer(size).Pass();
+ CHECK(mem);
+ bool success = mem->Map(size);
+ CHECK(success);
+ return new Buffer(GetNextId(), mem.Pass());
+}
+
+size_t CompositorSoftwareOutputDevice::FindFreeBuffer(size_t hint) {
+ for (size_t i = 0; i < buffers_.size(); ++i) {
+ size_t index = (hint + i) % buffers_.size();
+ if (buffers_[index]->free())
+ return index;
+ }
+
+ buffers_.push_back(CreateBuffer());
+ return buffers_.size() - 1;
}
void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
@@ -50,66 +103,76 @@ void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
if (viewport_size_ == viewport_size)
return;
- // Keep non-ACKed dibs open.
- int first_non_free = front_buffer_ + num_free_buffers_ + 1;
- int num_non_free = dibs_.size() - num_free_buffers_;
- for (int i = 0; i < num_non_free; ++i) {
- int index = (first_non_free + i) % dibs_.size();
- awaiting_ack_.push_back(dibs_[index]);
- dibs_[index] = NULL;
+ // Keep non-ACKed buffers in awaiting_ack_ until they get acknowledged.
+ for (size_t i = 0; i < buffers_.size(); ++i) {
+ if (!buffers_[i]->free()) {
+ awaiting_ack_.push_back(buffers_[i]);
+ buffers_[i] = NULL;
+ }
}
- dibs_.clear();
- front_buffer_ = -1;
- num_free_buffers_ = 0;
+ buffers_.clear();
+ current_index_ = -1;
viewport_size_ = viewport_size;
}
SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
DCHECK(CalledOnValidThread());
- gfx::Rect last_damage_rect = damage_rect_;
- damage_rect_ = damage_rect;
-
- int last_buffer = front_buffer_;
- if (num_free_buffers_ == 0) {
- dibs_.insert(dibs_.begin() + (front_buffer_ + 1), CreateDIB());
- last_damage_rect = gfx::Rect(viewport_size_);
- } else {
- --num_free_buffers_;
- }
- front_buffer_ = (front_buffer_ + 1) % dibs_.size();
-
- TransportDIB* front_dib = dibs_[front_buffer_]->dib();
- DCHECK(front_dib);
- DCHECK(front_dib->memory());
+ Buffer* previous = NULL;
+ if (current_index_ != size_t(-1))
+ previous = buffers_[current_index_];
+ current_index_ = FindFreeBuffer(current_index_ + 1);
+ Buffer* current = buffers_[current_index_];
+ DCHECK(current->free());
+ current->SetFree(false);
// Set up a canvas for the current front buffer.
bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
viewport_size_.width(),
viewport_size_.height());
- bitmap_.setPixels(front_dib->memory());
+ bitmap_.setPixels(current->memory());
device_ = skia::AdoptRef(new SkDevice(bitmap_));
canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
- // Copy over previous damage.
- if (last_buffer != -1) {
- TransportDIB* last_dib = dibs_[last_buffer]->dib();
- SkBitmap back_bitmap;
- back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- viewport_size_.width(),
- viewport_size_.height());
- back_bitmap.setPixels(last_dib->memory());
-
- SkRegion region(RectToSkIRect(last_damage_rect));
+ if (!previous) {
+ DCHECK(damage_rect == gfx::Rect(viewport_size_));
+ } else {
+ // Find the smallest damage region that needs
+ // to be copied from the |previous| buffer.
+ SkRegion region;
+ bool found =
+ current->FindDamageDifferenceFrom(previous, &region) ||
+ previous->FindDamageDifferenceFrom(current, &region);
+ if (!found)
+ region = SkRegion(RectToSkIRect(gfx::Rect(viewport_size_)));
region.op(RectToSkIRect(damage_rect), SkRegion::kDifference_Op);
- for (SkRegion::Iterator it(region); !it.done(); it.next()) {
- const SkIRect& src_rect = it.rect();
- SkRect dst_rect = SkRect::Make(src_rect);
- canvas_->drawBitmapRect(back_bitmap, &src_rect, dst_rect, NULL);
+
+ // Copy over the damage region.
+ if (!region.isEmpty()) {
+ SkBitmap back_bitmap;
+ back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ viewport_size_.width(),
+ viewport_size_.height());
+ back_bitmap.setPixels(previous->memory());
+
+ for (SkRegion::Iterator it(region); !it.done(); it.next()) {
+ const SkIRect& src_rect = it.rect();
+ SkRect dst_rect = SkRect::Make(src_rect);
+ canvas_->drawBitmapRect(back_bitmap, &src_rect, dst_rect, NULL);
+ }
}
}
+ // Make |current| child of |previous| and orphan all of |current|'s children.
+ current->SetParent(previous, damage_rect);
+ for (size_t i = 0; i < buffers_.size(); ++i) {
+ Buffer* buffer = buffers_[i];
+ if (buffer->parent() == current)
+ buffer->SetParent(NULL, gfx::Rect(viewport_size_));
+ }
+ damage_rect_ = damage_rect;
+
return canvas_.get();
}
@@ -118,25 +181,27 @@ void CompositorSoftwareOutputDevice::EndPaint(
DCHECK(CalledOnValidThread());
if (frame_data) {
+ Buffer* buffer = buffers_[current_index_];
+ frame_data->id = buffer->id();
frame_data->size = viewport_size_;
frame_data->damage_rect = damage_rect_;
- frame_data->dib_id = dibs_[front_buffer_]->dib()->id();
+ frame_data->handle = buffer->handle();
}
}
-void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) {
+void CompositorSoftwareOutputDevice::ReclaimSoftwareFrame(unsigned id) {
DCHECK(CalledOnValidThread());
- if (!TransportDIB::is_valid_id(id))
+ if (!id)
return;
- // The reclaimed dib id might not be among the currently
- // active dibs if we got a resize event in the mean time.
- ScopedVector<DIB>::iterator it =
- std::find_if(dibs_.begin(), dibs_.end(), CompareById(id));
- if (it != dibs_.end()) {
- ++num_free_buffers_;
- DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
+ // The reclaimed buffer id might not be among the currently
+ // active buffers if we got a resize event in the mean time.
+ ScopedVector<Buffer>::iterator it =
+ std::find_if(buffers_.begin(), buffers_.end(), CompareById(id));
+ if (it != buffers_.end()) {
+ DCHECK(!(*it)->free());
+ (*it)->SetFree(true);
return;
} else {
it = std::find_if(awaiting_ack_.begin(), awaiting_ack_.end(),
« no previous file with comments | « content/renderer/gpu/compositor_software_output_device.h ('k') | gpu/command_buffer/common/mailbox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698