software_renderer.cc revision 868fa2fe829687343ffae624259930155e16dbd8
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/software_renderer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_ack.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_metadata.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/output/copy_output_request.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/software_output_device.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/debug_border_draw_quad.h"
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "cc/quads/picture_draw_quad.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/render_pass_draw_quad.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/solid_color_draw_quad.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/texture_draw_quad.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/tile_draw_quad.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkDevice.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkMatrix.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkShader.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/effects/SkLayerRasterizer.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/skia_util.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsScaleAndTranslate(const SkMatrix& matrix) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // anonymous namespace
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<SoftwareRenderer> SoftwareRenderer::Create(
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RendererClient* client,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OutputSurface* output_surface,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new SoftwareRenderer(client, output_surface, resource_provider));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareRenderer::SoftwareRenderer(RendererClient* client,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   OutputSurface* output_surface,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   ResourceProvider* resource_provider)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  : DirectRenderer(client, output_surface, resource_provider),
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visible_(true),
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_scissor_enabled_(false),
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    is_viewport_changed_(true),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output_device_(output_surface->software_device()),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_(NULL) {
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (resource_provider_) {
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    capabilities_.max_texture_size = resource_provider_->max_texture_size();
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    capabilities_.best_texture_format =
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        resource_provider_->best_texture_format();
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_set_visibility = true;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The updater can access bitmaps while the SoftwareRenderer is using them.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.allow_partial_texture_updates = true;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_partial_swap = true;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Settings().compositor_frame_message && client_->HasImplThread())
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    capabilities_.using_swap_complete_callback = true;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  compositor_frame_.software_frame_data.reset(new SoftwareFrameData());
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareRenderer::~SoftwareRenderer() {}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const RendererCapabilities& SoftwareRenderer::Capabilities() const {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return capabilities_;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::ViewportChanged() {
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  is_viewport_changed_ = true;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_viewport_changed_) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    is_viewport_changed_ = false;
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    output_device_->Resize(client_->DeviceViewport().size());
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_canvas_ = output_device_->BeginPaint(
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::ToEnclosingRect(frame->root_damage_rect));
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame");
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = NULL;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_canvas_ = NULL;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Settings().compositor_frame_message) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    compositor_frame_.metadata = client_->MakeCompositorFrameMetadata();
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output_device_->EndPaint(compositor_frame_.software_frame_data.get());
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output_device_->EndPaint(NULL);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SoftwareRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Settings().compositor_frame_message)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output_surface_->SendFrameToParentCompositor(&compositor_frame_);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::ReceiveCompositorFrameAck(
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CompositorFrameAck& ack) {
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  output_device_->ReclaimSoftwareFrame(ack.last_software_frame_id);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::FlippedFramebuffer() const {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::EnsureScissorTestEnabled() {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetClipRect(scissor_rect_);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::EnsureScissorTestDisabled() {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There is no explicit notion of enabling/disabling scissoring in software
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // rendering, but the underlying effect we want is to clear any existing
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clipRect on the current SkCanvas. This is done by setting clipRect to
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the viewport's dimensions.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = false;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkDevice* device = current_canvas_->getDevice();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetClipRect(gfx::Rect(device->width(), device->height()));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::Finish() {}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = root_canvas_;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::BindFramebufferToTexture(
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ScopedResource* texture,
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    gfx::Rect target_rect) {
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_framebuffer_lock_.reset();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_ = make_scoped_ptr(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ResourceProvider::ScopedWriteLockSoftware(
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_provider_, texture->id()));
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = current_framebuffer_lock_->sk_canvas();
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  InitializeViewport(frame,
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     target_rect,
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     gfx::Rect(target_rect.size()),
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     target_rect.size(),
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     false);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::SetScissorTestRect(gfx::Rect scissor_rect) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scissor_rect_ = scissor_rect;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetClipRect(scissor_rect);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::SetClipRect(gfx::Rect rect) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skia applies the current matrix to clip rects so we reset it temporary.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix current_matrix = current_canvas_->getTotalMatrix();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->clipRect(gfx::RectToSkRect(rect), SkRegion::kReplace_Op);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->setMatrix(current_matrix);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::ClearCanvas(SkColor color) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SkCanvas::clear doesn't respect the current clipping region
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so we SkCanvas::drawColor instead if scissoring is active.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_scissor_enabled_)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->drawColor(color, SkXfermode::kSrc_Mode);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->clear(color);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (frame->current_render_pass->has_transparent_background) {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClearCanvas(SkColorSetARGB(0, 0, 0, 0));
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On DEBUG builds, opaque render passes are cleared to blue
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to easily see regions that were not drawn on the screen.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClearCanvas(SkColorSetARGB(255, 0, 0, 255));
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SoftwareRenderer::SetDrawViewport(gfx::Rect window_space_viewport) {}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::IsSoftwareResource(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id) const {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (resource_provider_->GetResourceType(resource_id)) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ResourceProvider::GLTexture:
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ResourceProvider::Bitmap:
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(FATAL) << "Invalid resource type.";
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad");
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform =
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_device_transform.FlattenTo2d();
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix sk_device_matrix;
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::TransformToFlattenedSkMatrix(contents_device_transform,
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    &sk_device_matrix);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->setMatrix(sk_device_matrix);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.reset();
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsScaleAndTranslate(sk_device_matrix)) {
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(danakj): Until we can enable AA only on exterior edges of the
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // layer, disable AA if any interior edges are present. crbug.com/248175
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool all_four_edges_are_exterior = quad->IsTopEdge() &&
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsLeftEdge() &&
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsBottomEdge() &&
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsRightEdge();
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (all_four_edges_are_exterior)
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      current_paint_.setAntiAlias(true);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setFilterBitmap(true);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->ShouldDrawWithBlending()) {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setAlpha(quad->opacity() * 255);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setXfermodeMode(SkXfermode::kSrcOver_Mode);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setXfermodeMode(SkXfermode::kSrc_Mode);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (quad->material) {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::DEBUG_BORDER:
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case DrawQuad::PICTURE_CONTENT:
249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad));
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::SOLID_COLOR:
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TEXTURE_CONTENT:
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TILED_CONTENT:
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::RENDER_PASS:
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawUnsupportedQuad(frame, quad);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const DebugBorderDrawQuad* quad) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We need to apply the matrix manually to have pixel-sized stroke width.
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPoint vertices[4];
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPoint transformed_vertices[4];
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->getTotalMatrix().mapPoints(transformed_vertices,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              vertices,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              4);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(quad->color);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setStyle(SkPaint::kStroke_Style);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setStrokeWidth(quad->width);
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              4, transformed_vertices, current_paint_);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame,
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                       const PictureDrawQuad* quad) {
292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SkMatrix content_matrix;
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  content_matrix.setRectToRect(
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      gfx::RectFToSkRect(quad->tex_coord_rect),
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      gfx::RectFToSkRect(QuadVertexRect()),
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      SkMatrix::kFill_ScaleToFit);
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_canvas_->concat(content_matrix);
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (quad->ShouldDrawWithBlending()) {
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    TRACE_EVENT0("cc", "SoftwareRenderer::DrawPictureQuad with blending");
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    SkBitmap temp_bitmap;
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                          quad->texture_size.width(),
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                          quad->texture_size.height());
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    temp_bitmap.allocPixels();
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    SkDevice temp_device(temp_bitmap);
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    SkCanvas temp_canvas(&temp_device);
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    quad->picture_pile->RasterToBitmap(
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        &temp_canvas, quad->content_rect, quad->contents_scale, NULL);
311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    current_paint_.setFilterBitmap(true);
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    current_canvas_->drawBitmap(temp_bitmap, 0, 0, &current_paint_);
314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  } else {
315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    TRACE_EVENT0("cc",
316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 "SoftwareRenderer::DrawPictureQuad direct from PicturePile");
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    quad->picture_pile->RasterDirect(
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        current_canvas_, quad->content_rect, quad->contents_scale, NULL);
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const SolidColorDrawQuad* quad) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(quad->color);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()),
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_paint_);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame,
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const TextureDrawQuad* quad) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsSoftwareResource(quad->resource_id)) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawUnsupportedQuad(frame, quad);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FIXME: Add support for non-premultiplied alpha.
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                quad->resource_id);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SkBitmap* bitmap = lock.sk_bitmap();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_rect = gfx::ScaleRect(gfx::BoundingRect(quad->uv_top_left,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        quad->uv_bottom_right),
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bitmap->width(),
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bitmap->height());
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect sk_uv_rect = gfx::RectFToSkRect(uv_rect);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->flipped)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->scale(1, -1);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawBitmapRectToRect(*bitmap, &sk_uv_rect,
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        gfx::RectFToSkRect(QuadVertexRect()),
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        &current_paint_);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const TileDrawQuad* quad) {
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(!output_surface_->ForcedDrawToSoftwareDevice());
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsSoftwareResource(quad->resource_id));
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                quad->resource_id);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect uv_rect = gfx::RectFToSkRect(quad->tex_coord_rect);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setFilterBitmap(true);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawBitmapRectToRect(*lock.sk_bitmap(), &uv_rect,
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        gfx::RectFToSkRect(QuadVertexRect()),
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        &current_paint_);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const RenderPassDrawQuad* quad) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CachedResource* content_texture =
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_pass_textures_.get(quad->render_pass_id);
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!content_texture || !content_texture->id())
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsSoftwareResource(content_texture->id()));
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                content_texture->id());
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect());
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height());
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix content_mat;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content_mat.setRectToRect(content_rect, dest_rect,
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            SkMatrix::kFill_ScaleToFit);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SkBitmap* content = lock.sk_bitmap();
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkShader::CreateBitmapShader(*content,
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   SkShader::kClamp_TileMode,
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   SkShader::kClamp_TileMode));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shader->setLocalMatrix(content_mat);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setShader(shader.get());
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkImageFilter* filter = quad->filter.get();
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (filter)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setImageFilter(filter);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->mask_resource_id) {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware mask_lock(resource_provider_,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       quad->mask_resource_id);
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SkBitmap* mask = mask_lock.sk_bitmap();
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkRect mask_rect = SkRect::MakeXYWH(
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.x() * mask->width(),
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.y() * mask->height(),
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.width() * mask->width(),
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.height() * mask->height());
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkMatrix mask_mat;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_mat.setRectToRect(mask_rect, dest_rect, SkMatrix::kFill_ScaleToFit);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkShader> mask_shader = skia::AdoptRef(
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SkShader::CreateBitmapShader(*mask,
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     SkShader::kClamp_TileMode,
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     SkShader::kClamp_TileMode));
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_shader->setLocalMatrix(mask_mat);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPaint mask_paint;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_paint.setShader(mask_shader.get());
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkLayerRasterizer> mask_rasterizer =
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        skia::AdoptRef(new SkLayerRasterizer);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_rasterizer->addLayer(mask_paint);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setRasterizer(mask_rasterizer.get());
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->drawRect(dest_rect, current_paint_);
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // FIXME: Apply background filters and blend with content
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->drawRect(dest_rect, current_paint_);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame,
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const DrawQuad* quad) {
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef NDEBUG
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(SK_ColorWHITE);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(SK_ColorMAGENTA);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * 255);
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()),
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_paint_);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::CopyCurrentRenderPassToBitmap(
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    current_viewport_rect_.width(),
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    current_viewport_rect_.height());
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  current_canvas_->readPixels(
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      bitmap.get(), current_viewport_rect_.x(), current_viewport_rect_.y());
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  request->SendBitmapResult(bitmap.Pass());
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::GetFramebufferPixels");
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap subset_bitmap;
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rect += current_viewport_rect_.OffsetFromOrigin();
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output_device_->CopyToBitmap(rect, &subset_bitmap);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  subset_bitmap.copyPixelsTo(pixels,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             4 * rect.width() * rect.height(),
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             4 * rect.width());
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::SetVisible(bool visible) {
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visible_ == visible)
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visible_ = visible;
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
475