Commit 2847b22b authored by skaslev@chromium.org's avatar skaslev@chromium.org

Browser side changes for software compositing.

BUG=124671, 161008

NOTRY=true

Review URL: https://chromiumcodereview.appspot.com/13042012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192678 0039d316-1c4b-4281-b951-d872f2087c98
parent 915388f3
......@@ -67,6 +67,7 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client,
: DirectRenderer(client, resource_provider),
visible_(true),
is_scissor_enabled_(false),
is_viewport_changed_(true),
output_surface_(output_surface),
output_device_(output_surface->software_device()),
current_canvas_(NULL) {
......@@ -81,8 +82,6 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client,
if (Settings().compositor_frame_message && client_->HasImplThread())
capabilities_.using_swap_complete_callback = true;
compositor_frame_.software_frame_data.reset(new SoftwareFrameData());
ViewportChanged();
}
SoftwareRenderer::~SoftwareRenderer() {}
......@@ -92,11 +91,15 @@ const RendererCapabilities& SoftwareRenderer::Capabilities() const {
}
void SoftwareRenderer::ViewportChanged() {
output_device_->Resize(ViewportSize());
is_viewport_changed_ = true;
}
void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
if (is_viewport_changed_) {
is_viewport_changed_ = false;
output_device_->Resize(ViewportSize());
}
root_canvas_ = output_device_->BeginPaint(
gfx::ToEnclosingRect(frame->root_damage_rect));
}
......
......@@ -85,6 +85,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
RendererCapabilities capabilities_;
bool visible_;
bool is_scissor_enabled_;
bool is_viewport_changed_;
gfx::Rect scissor_rect_;
OutputSurface* output_surface_;
......
......@@ -1619,6 +1619,8 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame(
ack.gl_frame_data->sync_point = 0;
} else if (frame->delegated_frame_data) {
ack.resources.swap(frame->delegated_frame_data->resource_list);
} else if (frame->software_frame_data) {
ack.last_dib_id = frame->software_frame_data->dib_id;
}
SendSwapCompositorFrameAck(routing_id_, process_->GetID(), ack);
}
......
......@@ -316,7 +316,7 @@ class RenderWidgetHostViewAura
virtual ~RenderWidgetHostViewAura();
void UpdateCursorIfOverSelf();
bool ShouldSkipFrame(gfx::Size size_in_dip);
bool ShouldSkipFrame(gfx::Size size_in_dip) const;
void CheckResizeLocks(gfx::Size size_in_dip);
void UpdateExternalTexture();
ui::InputMethod* GetInputMethod() const;
......@@ -340,8 +340,11 @@ class RenderWidgetHostViewAura
// moved to center.
bool ShouldMoveToCenter();
// Run the compositing callbacks.
void RunCompositingDidCommitCallbacks();
// Run all on compositing commit callbacks.
void RunOnCommitCallbacks();
// Add on compositing commit callback.
void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
// Called after |window_| is parented to a RootWindow.
void AddedToRootWindow();
......@@ -391,10 +394,15 @@ class RenderWidgetHostViewAura
const scoped_refptr<ui::Texture>& texture_to_return);
void SwapDelegatedFrame(
scoped_ptr<cc::DelegatedFrameData> frame,
float device_scale_factor);
scoped_ptr<cc::DelegatedFrameData> frame_data,
float frame_device_scale_factor);
void SendDelegatedFrameAck();
void SwapSoftwareFrame(
scoped_ptr<cc::SoftwareFrameData> frame_data,
float frame_device_scale_factor);
void SendSoftwareFrameAck(const TransportDIB::Id& id);
BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
#if defined(OS_WIN)
......@@ -471,6 +479,13 @@ class RenderWidgetHostViewAura
// The current frontbuffer texture.
scoped_refptr<ui::Texture> current_surface_;
// The current frontbuffer DIB.
scoped_ptr<TransportDIB> current_dib_;
// The current DIB id as it was received from the renderer. Note that on
// some platforms (e.g. Windows) this is different from current_dib_->id().
TransportDIB::Id current_dib_id_;
// The damage in the previously presented buffer.
SkRegion previous_damage_;
......
......@@ -32,8 +32,7 @@ class CompareById {
} // namespace
CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
: front_buffer_(0),
last_buffer_(-1),
: front_buffer_(-1),
num_free_buffers_(0),
sequence_num_(0) {
DetachFromThread();
......@@ -55,38 +54,44 @@ TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() {
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();
// 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;
}
dibs_.clear();
front_buffer_ = 0;
front_buffer_ = -1;
num_free_buffers_ = 0;
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_, CreateDIB());
num_free_buffers_++;
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_];
DCHECK(front_dib);
DCHECK(front_dib->memory());
// Set up a canvas for the front_dib.
// Set up a canvas for the current front buffer.
bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
viewport_size_.width(),
viewport_size_.height());
......@@ -94,19 +99,23 @@ SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
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_];
// Copy over previous damage.
if (last_buffer != -1) {
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);
SkRegion region(RectToSkIRect(last_damage_rect));
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);
}
}
damage_rect_ = damage_rect;
return canvas_.get();
}
......@@ -120,30 +129,28 @@ void CompositorSoftwareOutputDevice::EndPaint(
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
if (!TransportDIB::is_valid_id(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<TransportDIB>::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());
return;
} else {
it = std::find_if(awaiting_ack_.begin(),
awaiting_ack_.end(),
it = std::find_if(awaiting_ack_.begin(), awaiting_ack_.end(),
CompareById(id));
DCHECK(it != awaiting_ack_.end());
awaiting_ack_.erase(it);
}
DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
}
} // namespace content
......@@ -33,7 +33,6 @@ private:
TransportDIB* CreateDIB();
int front_buffer_;
int last_buffer_;
int num_free_buffers_;
ScopedVector<TransportDIB> dibs_;
ScopedVector<TransportDIB> awaiting_ack_;
......
......@@ -24,7 +24,7 @@
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/gpu/compositor_output_surface.h"
#include "content/renderer/gpu/compositor_software_output_device_gl_adapter.h"
#include "content/renderer/gpu/compositor_software_output_device.h"
#include "content/renderer/gpu/input_handler_manager.h"
#include "content/renderer/gpu/mailbox_output_surface.h"
#include "content/renderer/gpu/render_widget_compositor.h"
......@@ -555,6 +555,13 @@ bool RenderWidget::ForceCompositingModeEnabled() {
}
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) {
return scoped_ptr<cc::OutputSurface>(
new CompositorOutputSurface(routing_id(), NULL,
new CompositorSoftwareOutputDevice()));
}
// Explicitly disable antialiasing for the compositor. As of the time of
// this writing, the only platform that supported antialiasing for the
// compositor was Mac OS X, because the on-screen OpenGL context creation
......@@ -573,15 +580,6 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
if (!context)
return scoped_ptr<cc::OutputSurface>();
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) {
// In the absence of a software-based delegating renderer, use this
// stopgap adapter class to present the software renderer output using a
// 3d context.
return scoped_ptr<cc::OutputSurface>(
new CompositorOutputSurface(routing_id(), NULL,
new CompositorSoftwareOutputDeviceGLAdapter(context)));
} else {
bool composite_to_mailbox =
command_line.HasSwitch(cc::switches::kCompositeToMailbox);
DCHECK(!composite_to_mailbox || command_line.HasSwitch(
......@@ -591,7 +589,6 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ?
new MailboxOutputSurface(routing_id(), context, NULL) :
new CompositorOutputSurface(routing_id(), context, NULL));
}
}
void RenderWidget::OnViewContextSwapBuffersAborted() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment