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, ...@@ -67,6 +67,7 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client,
: DirectRenderer(client, resource_provider), : DirectRenderer(client, resource_provider),
visible_(true), visible_(true),
is_scissor_enabled_(false), is_scissor_enabled_(false),
is_viewport_changed_(true),
output_surface_(output_surface), output_surface_(output_surface),
output_device_(output_surface->software_device()), output_device_(output_surface->software_device()),
current_canvas_(NULL) { current_canvas_(NULL) {
...@@ -81,8 +82,6 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client, ...@@ -81,8 +82,6 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client,
if (Settings().compositor_frame_message && client_->HasImplThread()) if (Settings().compositor_frame_message && client_->HasImplThread())
capabilities_.using_swap_complete_callback = true; capabilities_.using_swap_complete_callback = true;
compositor_frame_.software_frame_data.reset(new SoftwareFrameData()); compositor_frame_.software_frame_data.reset(new SoftwareFrameData());
ViewportChanged();
} }
SoftwareRenderer::~SoftwareRenderer() {} SoftwareRenderer::~SoftwareRenderer() {}
...@@ -92,11 +91,15 @@ const RendererCapabilities& SoftwareRenderer::Capabilities() const { ...@@ -92,11 +91,15 @@ const RendererCapabilities& SoftwareRenderer::Capabilities() const {
} }
void SoftwareRenderer::ViewportChanged() { void SoftwareRenderer::ViewportChanged() {
output_device_->Resize(ViewportSize()); is_viewport_changed_ = true;
} }
void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) { void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame"); TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
if (is_viewport_changed_) {
is_viewport_changed_ = false;
output_device_->Resize(ViewportSize());
}
root_canvas_ = output_device_->BeginPaint( root_canvas_ = output_device_->BeginPaint(
gfx::ToEnclosingRect(frame->root_damage_rect)); gfx::ToEnclosingRect(frame->root_damage_rect));
} }
......
...@@ -85,6 +85,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { ...@@ -85,6 +85,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
RendererCapabilities capabilities_; RendererCapabilities capabilities_;
bool visible_; bool visible_;
bool is_scissor_enabled_; bool is_scissor_enabled_;
bool is_viewport_changed_;
gfx::Rect scissor_rect_; gfx::Rect scissor_rect_;
OutputSurface* output_surface_; OutputSurface* output_surface_;
......
...@@ -1619,6 +1619,8 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame( ...@@ -1619,6 +1619,8 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame(
ack.gl_frame_data->sync_point = 0; ack.gl_frame_data->sync_point = 0;
} else if (frame->delegated_frame_data) { } else if (frame->delegated_frame_data) {
ack.resources.swap(frame->delegated_frame_data->resource_list); 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); SendSwapCompositorFrameAck(routing_id_, process_->GetID(), ack);
} }
......
...@@ -316,7 +316,7 @@ class RenderWidgetHostViewAura ...@@ -316,7 +316,7 @@ class RenderWidgetHostViewAura
virtual ~RenderWidgetHostViewAura(); virtual ~RenderWidgetHostViewAura();
void UpdateCursorIfOverSelf(); 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 CheckResizeLocks(gfx::Size size_in_dip);
void UpdateExternalTexture(); void UpdateExternalTexture();
ui::InputMethod* GetInputMethod() const; ui::InputMethod* GetInputMethod() const;
...@@ -340,8 +340,11 @@ class RenderWidgetHostViewAura ...@@ -340,8 +340,11 @@ class RenderWidgetHostViewAura
// moved to center. // moved to center.
bool ShouldMoveToCenter(); bool ShouldMoveToCenter();
// Run the compositing callbacks. // Run all on compositing commit callbacks.
void RunCompositingDidCommitCallbacks(); void RunOnCommitCallbacks();
// Add on compositing commit callback.
void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
// Called after |window_| is parented to a RootWindow. // Called after |window_| is parented to a RootWindow.
void AddedToRootWindow(); void AddedToRootWindow();
...@@ -391,10 +394,15 @@ class RenderWidgetHostViewAura ...@@ -391,10 +394,15 @@ class RenderWidgetHostViewAura
const scoped_refptr<ui::Texture>& texture_to_return); const scoped_refptr<ui::Texture>& texture_to_return);
void SwapDelegatedFrame( void SwapDelegatedFrame(
scoped_ptr<cc::DelegatedFrameData> frame, scoped_ptr<cc::DelegatedFrameData> frame_data,
float device_scale_factor); float frame_device_scale_factor);
void SendDelegatedFrameAck(); void SendDelegatedFrameAck();
void SwapSoftwareFrame(
scoped_ptr<cc::SoftwareFrameData> frame_data,
float frame_device_scale_factor);
void SendSoftwareFrameAck(const TransportDIB::Id& id);
BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager(); BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -471,6 +479,13 @@ class RenderWidgetHostViewAura ...@@ -471,6 +479,13 @@ class RenderWidgetHostViewAura
// The current frontbuffer texture. // The current frontbuffer texture.
scoped_refptr<ui::Texture> current_surface_; 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. // The damage in the previously presented buffer.
SkRegion previous_damage_; SkRegion previous_damage_;
......
...@@ -32,8 +32,7 @@ class CompareById { ...@@ -32,8 +32,7 @@ class CompareById {
} // namespace } // namespace
CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice() CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
: front_buffer_(0), : front_buffer_(-1),
last_buffer_(-1),
num_free_buffers_(0), num_free_buffers_(0),
sequence_num_(0) { sequence_num_(0) {
DetachFromThread(); DetachFromThread();
...@@ -55,38 +54,44 @@ TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() { ...@@ -55,38 +54,44 @@ TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() {
void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) { void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
// Reset last_buffer_ so that we don't copy over old damage.
last_buffer_ = -1;
if (viewport_size_ == viewport_size) if (viewport_size_ == viewport_size)
return; return;
viewport_size_ = viewport_size;
// Keep non-acked dibs open. // Keep non-ACKed dibs open.
for (size_t i = 0; i < dibs_.size() - num_free_buffers_; ++i) { int first_non_free = front_buffer_ + num_free_buffers_ + 1;
size_t index = (front_buffer_ + num_free_buffers_ + i) % dibs_.size(); 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]); awaiting_ack_.push_back(dibs_[index]);
dibs_[index] = NULL; dibs_[index] = NULL;
} }
dibs_.clear(); dibs_.clear();
front_buffer_ = 0; front_buffer_ = -1;
num_free_buffers_ = 0; num_free_buffers_ = 0;
viewport_size_ = viewport_size;
} }
SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) { SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
gfx::Rect last_damage_rect = damage_rect_;
damage_rect_ = damage_rect;
int last_buffer = front_buffer_;
if (num_free_buffers_ == 0) { if (num_free_buffers_ == 0) {
dibs_.insert(dibs_.begin() + front_buffer_, CreateDIB()); dibs_.insert(dibs_.begin() + (front_buffer_ + 1), CreateDIB());
num_free_buffers_++; last_damage_rect = gfx::Rect(viewport_size_);
} else {
--num_free_buffers_;
} }
front_buffer_ = (front_buffer_ + 1) % dibs_.size();
TransportDIB* front_dib = dibs_[front_buffer_]; TransportDIB* front_dib = dibs_[front_buffer_];
DCHECK(front_dib); DCHECK(front_dib);
DCHECK(front_dib->memory()); 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, bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
viewport_size_.width(), viewport_size_.width(),
viewport_size_.height()); viewport_size_.height());
...@@ -94,19 +99,23 @@ SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) { ...@@ -94,19 +99,23 @@ SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
device_ = skia::AdoptRef(new SkDevice(bitmap_)); device_ = skia::AdoptRef(new SkDevice(bitmap_));
canvas_ = skia::AdoptRef(new SkCanvas(device_.get())); canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
// Copy damage_rect_ from last_buffer_ to front_buffer_. // Copy over previous damage.
if (last_buffer_ != -1 && !damage_rect.Contains(damage_rect_)) { if (last_buffer != -1) {
TransportDIB* last_dib = dibs_[last_buffer_]; TransportDIB* last_dib = dibs_[last_buffer];
SkBitmap back_bitmap; SkBitmap back_bitmap;
back_bitmap.setConfig(SkBitmap::kARGB_8888_Config, back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
viewport_size_.width(), viewport_size_.width(),
viewport_size_.height()); viewport_size_.height());
back_bitmap.setPixels(last_dib->memory()); back_bitmap.setPixels(last_dib->memory());
SkRect last_damage = gfx::RectToSkRect(damage_rect_); SkRegion region(RectToSkIRect(last_damage_rect));
canvas_->drawBitmapRectToRect(back_bitmap, &last_damage, last_damage, NULL); 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(); return canvas_.get();
} }
...@@ -120,30 +129,28 @@ void CompositorSoftwareOutputDevice::EndPaint( ...@@ -120,30 +129,28 @@ void CompositorSoftwareOutputDevice::EndPaint(
frame_data->damage_rect = damage_rect_; frame_data->damage_rect = damage_rect_;
frame_data->dib_id = dibs_[front_buffer_]->id(); 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) { void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) {
DCHECK(CalledOnValidThread()); 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. // active dibs if we got a resize event in the mean time.
ScopedVector<TransportDIB>::iterator it = ScopedVector<TransportDIB>::iterator it =
std::find_if(dibs_.begin(), dibs_.end(), CompareById(id)); std::find_if(dibs_.begin(), dibs_.end(), CompareById(id));
if (it != dibs_.end()) { if (it != dibs_.end()) {
++num_free_buffers_; ++num_free_buffers_;
DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
return;
} else { } else {
it = std::find_if(awaiting_ack_.begin(), it = std::find_if(awaiting_ack_.begin(), awaiting_ack_.end(),
awaiting_ack_.end(),
CompareById(id)); CompareById(id));
DCHECK(it != awaiting_ack_.end());
awaiting_ack_.erase(it); awaiting_ack_.erase(it);
} }
DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
} }
} // namespace content } // namespace content
...@@ -33,7 +33,6 @@ private: ...@@ -33,7 +33,6 @@ private:
TransportDIB* CreateDIB(); TransportDIB* CreateDIB();
int front_buffer_; int front_buffer_;
int last_buffer_;
int num_free_buffers_; int num_free_buffers_;
ScopedVector<TransportDIB> dibs_; ScopedVector<TransportDIB> dibs_;
ScopedVector<TransportDIB> awaiting_ack_; ScopedVector<TransportDIB> awaiting_ack_;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/renderer/gpu/compositor_output_surface.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/input_handler_manager.h"
#include "content/renderer/gpu/mailbox_output_surface.h" #include "content/renderer/gpu/mailbox_output_surface.h"
#include "content/renderer/gpu/render_widget_compositor.h" #include "content/renderer/gpu/render_widget_compositor.h"
...@@ -555,6 +555,13 @@ bool RenderWidget::ForceCompositingModeEnabled() { ...@@ -555,6 +555,13 @@ bool RenderWidget::ForceCompositingModeEnabled() {
} }
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() { 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 // Explicitly disable antialiasing for the compositor. As of the time of
// this writing, the only platform that supported antialiasing for the // this writing, the only platform that supported antialiasing for the
// compositor was Mac OS X, because the on-screen OpenGL context creation // compositor was Mac OS X, because the on-screen OpenGL context creation
...@@ -573,25 +580,15 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() { ...@@ -573,25 +580,15 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
if (!context) if (!context)
return scoped_ptr<cc::OutputSurface>(); return scoped_ptr<cc::OutputSurface>();
const CommandLine& command_line = *CommandLine::ForCurrentProcess(); bool composite_to_mailbox =
if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) { command_line.HasSwitch(cc::switches::kCompositeToMailbox);
// In the absence of a software-based delegating renderer, use this DCHECK(!composite_to_mailbox || command_line.HasSwitch(
// stopgap adapter class to present the software renderer output using a cc::switches::kEnableCompositorFrameMessage));
// 3d context. // No swap throttling yet when compositing on the main thread.
return scoped_ptr<cc::OutputSurface>( DCHECK(!composite_to_mailbox || is_threaded_compositing_enabled_);
new CompositorOutputSurface(routing_id(), NULL, return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ?
new CompositorSoftwareOutputDeviceGLAdapter(context))); new MailboxOutputSurface(routing_id(), context, NULL) :
} else { new CompositorOutputSurface(routing_id(), context, NULL));
bool composite_to_mailbox =
command_line.HasSwitch(cc::switches::kCompositeToMailbox);
DCHECK(!composite_to_mailbox || command_line.HasSwitch(
cc::switches::kEnableCompositorFrameMessage));
// No swap throttling yet when compositing on the main thread.
DCHECK(!composite_to_mailbox || is_threaded_compositing_enabled_);
return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ?
new MailboxOutputSurface(routing_id(), context, NULL) :
new CompositorOutputSurface(routing_id(), context, NULL));
}
} }
void RenderWidget::OnViewContextSwapBuffersAborted() { 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