summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/renderer/gpu/compositor_output_surface.cc2
-rw-r--r--content/renderer/gpu/compositor_output_surface.h1
-rw-r--r--content/renderer/gpu/compositor_software_output_device.cc149
-rw-r--r--content/renderer/gpu/compositor_software_output_device.h46
-rw-r--r--ui/surface/transport_dib.h4
6 files changed, 202 insertions, 2 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index a0f3c07..d6d2c27 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -94,6 +94,8 @@
'renderer/geolocation_dispatcher.h',
'renderer/gpu/compositor_output_surface.cc',
'renderer/gpu/compositor_output_surface.h',
+ 'renderer/gpu/compositor_software_output_device.cc',
+ 'renderer/gpu/compositor_software_output_device.h',
'renderer/gpu/compositor_software_output_device_gl_adapter.cc',
'renderer/gpu/compositor_software_output_device_gl_adapter.h',
'renderer/gpu/input_event_filter.cc',
diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc
index cc55ffa..a1b8fff 100644
--- a/content/renderer/gpu/compositor_output_surface.cc
+++ b/content/renderer/gpu/compositor_output_surface.cc
@@ -22,8 +22,6 @@
#include <sys/resource.h>
#endif
-using cc::CompositorFrame;
-using cc::SoftwareOutputDevice;
using WebKit::WebGraphicsContext3D;
namespace {
diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h
index 255c618..3de9892 100644
--- a/content/renderer/gpu/compositor_output_surface.h
+++ b/content/renderer/gpu/compositor_output_surface.h
@@ -24,6 +24,7 @@ class Message;
}
namespace cc {
+class CompositorFrame;
class CompositorFrameAck;
}
diff --git a/content/renderer/gpu/compositor_software_output_device.cc b/content/renderer/gpu/compositor_software_output_device.cc
new file mode 100644
index 0000000..77fbdb3
--- /dev/null
+++ b/content/renderer/gpu/compositor_software_output_device.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/gpu/compositor_software_output_device.h"
+
+#include "base/logging.h"
+#include "cc/output/software_frame_data.h"
+#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 "ui/gfx/skia_util.h"
+
+namespace content {
+
+namespace {
+
+class CompareById {
+ public:
+ CompareById(const TransportDIB::Id& id)
+ : id_(id) {
+ }
+
+ bool operator()(const TransportDIB* dib) const {
+ return dib->id() == id_;
+ }
+
+ private:
+ TransportDIB::Id id_;
+};
+
+} // namespace
+
+CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
+ : front_buffer_(0),
+ last_buffer_(-1),
+ num_free_buffers_(0),
+ sequence_num_(0) {
+ DetachFromThread();
+}
+
+CompositorSoftwareOutputDevice::~CompositorSoftwareOutputDevice() {
+ DCHECK(CalledOnValidThread());
+}
+
+TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() {
+ const size_t size = 4 * viewport_size_.GetArea();
+ TransportDIB* dib = TransportDIB::Create(size, sequence_num_++);
+ CHECK(dib);
+ bool success = dib->Map();
+ CHECK(success);
+ return dib;
+}
+
+void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
+ DCHECK(CalledOnValidThread());
+
+ // Reset last_buffer_ so that we don't copy over old damage.
+ last_buffer_ = -1;
+
+ if (viewport_size_ == viewport_size)
+ return;
+ viewport_size_ = viewport_size;
+
+ // Keep non-acked dibs open.
+ for (size_t i = 0; i < dibs_.size() - num_free_buffers_; ++i) {
+ size_t index = (front_buffer_ + num_free_buffers_ + i) % dibs_.size();
+ awaiting_ack_.push_back(dibs_[index]);
+ dibs_[index] = NULL;
+ }
+
+ dibs_.clear();
+ front_buffer_ = 0;
+ num_free_buffers_ = 0;
+}
+
+SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
+ DCHECK(CalledOnValidThread());
+
+ if (num_free_buffers_ == 0) {
+ dibs_.insert(dibs_.begin() + front_buffer_, CreateDIB());
+ num_free_buffers_++;
+ }
+
+ TransportDIB* front_dib = dibs_[front_buffer_];
+ DCHECK(front_dib);
+ DCHECK(front_dib->memory());
+
+ // Set up a canvas for the front_dib.
+ bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
+ viewport_size_.width(),
+ viewport_size_.height());
+ bitmap_.setPixels(front_dib->memory());
+ device_ = skia::AdoptRef(new SkDevice(bitmap_));
+ canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
+
+ // Copy damage_rect_ from last_buffer_ to front_buffer_.
+ if (last_buffer_ != -1 && !damage_rect.Contains(damage_rect_)) {
+ TransportDIB* last_dib = dibs_[last_buffer_];
+ SkBitmap back_bitmap;
+ back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ viewport_size_.width(),
+ viewport_size_.height());
+ back_bitmap.setPixels(last_dib->memory());
+
+ SkRect last_damage = gfx::RectToSkRect(damage_rect_);
+ canvas_->drawBitmapRectToRect(back_bitmap, &last_damage, last_damage, NULL);
+ }
+ damage_rect_ = damage_rect;
+
+ return canvas_.get();
+}
+
+void CompositorSoftwareOutputDevice::EndPaint(
+ cc::SoftwareFrameData* frame_data) {
+ DCHECK(CalledOnValidThread());
+
+ if (frame_data) {
+ frame_data->size = viewport_size_;
+ frame_data->damage_rect = damage_rect_;
+ frame_data->dib_id = dibs_[front_buffer_]->id();
+ }
+
+ last_buffer_ = front_buffer_;
+ front_buffer_ = (front_buffer_ + 1) % dibs_.size();
+ --num_free_buffers_;
+ DCHECK_GE(num_free_buffers_, 0);
+}
+
+void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) {
+ DCHECK(CalledOnValidThread());
+
+ // The reclaimed handle might not be among the currently
+ // active dibs if we got a resize event in the mean time.
+ ScopedVector<TransportDIB>::iterator it =
+ std::find_if(dibs_.begin(), dibs_.end(), CompareById(id));
+ if (it != dibs_.end()) {
+ ++num_free_buffers_;
+ } else {
+ it = std::find_if(awaiting_ack_.begin(),
+ awaiting_ack_.end(),
+ CompareById(id));
+ awaiting_ack_.erase(it);
+ }
+
+ DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
+}
+
+} // namespace content
diff --git a/content/renderer/gpu/compositor_software_output_device.h b/content/renderer/gpu/compositor_software_output_device.h
new file mode 100644
index 0000000..a639347
--- /dev/null
+++ b/content/renderer/gpu/compositor_software_output_device.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
+#define CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
+
+#include "base/memory/scoped_vector.h"
+#include "base/threading/non_thread_safe.h"
+#include "cc/output/software_output_device.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/surface/transport_dib.h"
+
+namespace content {
+
+// This class can be created only on the main thread, but then becomes pinned
+// to a fixed thread when BindToClient is called.
+class CompositorSoftwareOutputDevice
+ : NON_EXPORTED_BASE(public cc::SoftwareOutputDevice),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
+public:
+ CompositorSoftwareOutputDevice();
+ virtual ~CompositorSoftwareOutputDevice();
+
+ virtual void Resize(gfx::Size size) OVERRIDE;
+
+ virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE;
+ virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE;
+
+ virtual void ReclaimDIB(const TransportDIB::Id& id) OVERRIDE;
+
+private:
+ TransportDIB* CreateDIB();
+
+ int front_buffer_;
+ int last_buffer_;
+ int num_free_buffers_;
+ ScopedVector<TransportDIB> dibs_;
+ ScopedVector<TransportDIB> awaiting_ack_;
+ SkBitmap bitmap_;
+ uint32 sequence_num_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h
index 886afb9..a9d17d4 100644
--- a/ui/surface/transport_dib.h
+++ b/ui/surface/transport_dib.h
@@ -106,6 +106,10 @@ class SURFACE_EXPORT TransportDIB {
return shmkey < other.shmkey;
}
+ bool operator==(const Id& other) const {
+ return shmkey == other.shmkey;
+ }
+
int shmkey;
};