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"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "cc/output/render_surface_filters.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/software_output_device.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/quads/checkerboard_draw_quad.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/debug_border_draw_quad.h"
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "cc/quads/picture_draw_quad.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/render_pass_draw_quad.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/solid_color_draw_quad.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/texture_draw_quad.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/tile_draw_quad.h"
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "skia/ext/opacity_draw_filter.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "third_party/skia/include/core/SkImageFilter.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkMatrix.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkShader.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/effects/SkLayerRasterizer.h"
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/geometry/rect_conversions.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/skia_util.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static inline bool IsScalarNearlyInteger(SkScalar scalar) {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return SkScalarNearlyZero(scalar - SkScalarRoundToScalar(scalar));
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) {
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return IsScalarNearlyInteger(matrix[SkMatrix::kMTransX]) &&
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         IsScalarNearlyInteger(matrix[SkMatrix::kMTransY]) &&
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SkShader::TileMode WrapModeToTileMode(GLint wrap_mode) {
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (wrap_mode) {
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_REPEAT:
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SkShader::kRepeat_TileMode;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GL_CLAMP_TO_EDGE:
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return SkShader::kClamp_TileMode;
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED();
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return SkShader::kClamp_TileMode;
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // anonymous namespace
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<SoftwareRenderer> SoftwareRenderer::Create(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RendererClient* client,
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const LayerTreeSettings* settings,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OutputSurface* output_surface,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider) {
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return make_scoped_ptr(new SoftwareRenderer(
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      client, settings, output_surface, resource_provider));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareRenderer::SoftwareRenderer(RendererClient* client,
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const LayerTreeSettings* settings,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   OutputSurface* output_surface,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   ResourceProvider* resource_provider)
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : DirectRenderer(client, settings, output_surface, resource_provider),
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_scissor_enabled_(false),
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_backbuffer_discarded_(false),
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      output_device_(output_surface->software_device()),
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      current_canvas_(NULL) {
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (resource_provider_) {
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    capabilities_.max_texture_size = resource_provider_->max_texture_size();
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    capabilities_.best_texture_format =
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        resource_provider_->best_texture_format();
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The updater can access bitmaps while the SoftwareRenderer is using them.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.allow_partial_texture_updates = true;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  capabilities_.using_partial_swap = true;
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  capabilities_.using_shared_memory_resources = true;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  capabilities_.allow_rasterize_on_demand = true;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SoftwareRenderer::~SoftwareRenderer() {}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const RendererCapabilitiesImpl& SoftwareRenderer::Capabilities() const {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return capabilities_;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_canvas_ = output_device_->BeginPaint(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::ToEnclosingRect(frame->root_damage_rect));
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame");
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = NULL;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_canvas_ = NULL;
1135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
1145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  current_frame_data_.reset(new SoftwareFrameData);
1155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  output_device_->EndPaint(current_frame_data_.get());
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SoftwareRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc,benchmark", "SoftwareRenderer::SwapBuffers");
1205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  CompositorFrame compositor_frame;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  compositor_frame.metadata = metadata;
1225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  compositor_frame.software_frame_data = current_frame_data_.Pass();
1235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  output_surface_->SwapBuffers(&compositor_frame);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void SoftwareRenderer::ReceiveSwapBuffersAck(const CompositorFrameAck& ack) {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  output_device_->ReclaimSoftwareFrame(ack.last_software_frame_id);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::FlippedFramebuffer() const {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::EnsureScissorTestEnabled() {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetClipRect(scissor_rect_);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::EnsureScissorTestDisabled() {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There is no explicit notion of enabling/disabling scissoring in software
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // rendering, but the underlying effect we want is to clear any existing
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clipRect on the current SkCanvas. This is done by setting clipRect to
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the viewport's dimensions.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = false;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SkISize size = current_canvas_->getDeviceSize();
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetClipRect(gfx::Rect(size.width(), size.height()));
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::Finish() {}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!output_surface_->HasExternalStencilTest());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_.reset();
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = root_canvas_;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::BindFramebufferToTexture(
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ScopedResource* texture,
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& target_rect) {
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_framebuffer_lock_.reset();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_framebuffer_lock_ = make_scoped_ptr(
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ResourceProvider::ScopedWriteLockSoftware(
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_provider_, texture->id()));
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_ = current_framebuffer_lock_->sk_canvas();
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  InitializeViewport(frame,
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     target_rect,
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     gfx::Rect(target_rect.size()),
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     target_rect.size());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SoftwareRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_scissor_enabled_ = true;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scissor_rect_ = scissor_rect;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetClipRect(scissor_rect);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SoftwareRenderer::SetClipRect(const gfx::Rect& rect) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skia applies the current matrix to clip rects so we reset it temporary.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix current_matrix = current_canvas_->getTotalMatrix();
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->clipRect(gfx::RectToSkRect(rect), SkRegion::kReplace_Op);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->setMatrix(current_matrix);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SoftwareRenderer::ClearCanvas(SkColor color) {
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SkCanvas::clear doesn't respect the current clipping region
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so we SkCanvas::drawColor instead if scissoring is active.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_scissor_enabled_)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->drawColor(color, SkXfermode::kSrc_Mode);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->clear(color);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SoftwareRenderer::DiscardPixels(bool has_external_stencil_test,
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     bool draw_rect_covers_full_surface) {}
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame,
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                        bool has_external_stencil_test) {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (frame->current_render_pass->has_transparent_background) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClearCanvas(SkColorSetARGB(0, 0, 0, 0));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On DEBUG builds, opaque render passes are cleared to blue
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to easily see regions that were not drawn on the screen.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClearCanvas(SkColorSetARGB(255, 0, 0, 255));
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SoftwareRenderer::SetDrawViewport(
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& window_space_viewport) {}
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SoftwareRenderer::IsSoftwareResource(
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id) const {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (resource_provider_->GetResourceType(resource_id)) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ResourceProvider::GLTexture:
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ResourceProvider::Bitmap:
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case ResourceProvider::InvalidType:
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(FATAL) << "Invalid resource type.";
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) {
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad");
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform quad_rect_matrix;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform contents_device_transform =
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_device_transform.FlattenTo2d();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix sk_device_matrix;
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::TransformToFlattenedSkMatrix(contents_device_transform,
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    &sk_device_matrix);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->setMatrix(sk_device_matrix);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.reset();
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!IsScaleAndIntegerTranslate(sk_device_matrix)) {
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(danakj): Until we can enable AA only on exterior edges of the
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // layer, disable AA if any interior edges are present. crbug.com/248175
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool all_four_edges_are_exterior = quad->IsTopEdge() &&
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsLeftEdge() &&
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsBottomEdge() &&
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       quad->IsRightEdge();
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (settings_->allow_antialiasing && all_four_edges_are_exterior)
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      current_paint_.setAntiAlias(true);
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_paint_.setFilterLevel(SkPaint::kLow_FilterLevel);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (quad->ShouldDrawWithBlending() ||
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setAlpha(quad->opacity() * 255);
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    current_paint_.setXfermodeMode(quad->shared_quad_state->blend_mode);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setXfermodeMode(SkXfermode::kSrc_Mode);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (quad->material) {
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::CHECKERBOARD:
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad));
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::DEBUG_BORDER:
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case DrawQuad::PICTURE_CONTENT:
271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad));
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      break;
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::RENDER_PASS:
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::SOLID_COLOR:
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TEXTURE_CONTENT:
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case DrawQuad::TILED_CONTENT:
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case DrawQuad::SURFACE_CONTENT:
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Surface content should be fully resolved to other quad types before
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // reaching a direct renderer.
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::INVALID:
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::IO_SURFACE_CONTENT:
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::YUV_VIDEO_CONTENT:
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case DrawQuad::STREAM_VIDEO_CONTENT:
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DrawUnsupportedQuad(frame, quad);
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      NOTREACHED();
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SoftwareRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            const CheckerboardDrawQuad* quad) {
304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      QuadVertexRect(), quad->rect, quad->visible_rect);
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  current_paint_.setColor(quad->color);
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            current_paint_);
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const DebugBorderDrawQuad* quad) {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We need to apply the matrix manually to have pixel-sized stroke width.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPoint vertices[4];
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPoint transformed_vertices[4];
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->getTotalMatrix().mapPoints(transformed_vertices,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              vertices,
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              4);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->resetMatrix();
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(quad->color);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setStyle(SkPaint::kStroke_Style);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setStrokeWidth(quad->width);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              4, transformed_vertices, current_paint_);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame,
332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                       const PictureDrawQuad* quad) {
333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SkMatrix content_matrix;
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  content_matrix.setRectToRect(
335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      gfx::RectFToSkRect(quad->tex_coord_rect),
336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      gfx::RectFToSkRect(QuadVertexRect()),
337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      SkMatrix::kFill_ScaleToFit);
338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  current_canvas_->concat(content_matrix);
339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // TODO(aelias): This isn't correct in all cases. We should detect these
341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // cases and fall back to a persistent bitmap backing
342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // (http://crbug.com/280374).
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  skia::RefPtr<SkDrawFilter> opacity_filter =
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      skia::AdoptRef(new skia::OpacityDrawFilter(
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          quad->opacity(), frame->disable_picture_quad_image_filtering));
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!current_canvas_->getDrawFilter());
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  current_canvas_->setDrawFilter(opacity_filter.get());
348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc",
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)               "SoftwareRenderer::DrawPictureQuad");
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  quad->picture_pile->RasterDirect(
35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      current_canvas_, quad->content_rect, quad->contents_scale, NULL);
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  current_canvas_->setDrawFilter(NULL);
356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const SolidColorDrawQuad* quad) {
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      QuadVertexRect(), quad->rect, quad->visible_rect);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(quad->color);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_paint_);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame,
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const TextureDrawQuad* quad) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsSoftwareResource(quad->resource_id)) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawUnsupportedQuad(frame, quad);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(skaslev): Add support for non-premultiplied alpha.
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                quad->resource_id);
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!lock.valid())
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SkBitmap* bitmap = lock.sk_bitmap();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::RectF uv_rect = gfx::ScaleRect(gfx::BoundingRect(quad->uv_top_left,
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        quad->uv_bottom_right),
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bitmap->width(),
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      bitmap->height());
385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_uv_rect =
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      MathUtil::ScaleRectProportional(uv_rect, quad->rect, quad->visible_rect);
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkRect sk_uv_rect = gfx::RectFToSkRect(visible_uv_rect);
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      QuadVertexRect(), quad->rect, quad->visible_rect);
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkRect quad_rect = gfx::RectFToSkRect(visible_quad_vertex_rect);
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->flipped)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_canvas_->scale(1, -1);
3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool blend_background = quad->background_color != SK_ColorTRANSPARENT &&
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          !bitmap->isOpaque();
3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool needs_layer = blend_background && (current_paint_.getAlpha() != 0xFF);
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (needs_layer) {
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    current_canvas_->saveLayerAlpha(&quad_rect, current_paint_.getAlpha());
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    current_paint_.setAlpha(0xFF);
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (blend_background) {
4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SkPaint background_paint;
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    background_paint.setColor(quad->background_color);
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    current_canvas_->drawRect(quad_rect, background_paint);
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkShader::TileMode tile_mode = WrapModeToTileMode(lock.wrap_mode());
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (tile_mode != SkShader::kClamp_TileMode) {
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkMatrix matrix;
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    matrix.setRectToRect(sk_uv_rect, quad_rect, SkMatrix::kFill_ScaleToFit);
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    skia::RefPtr<SkShader> shader = skia::AdoptRef(
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        SkShader::CreateBitmapShader(*bitmap, tile_mode, tile_mode, &matrix));
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkPaint paint;
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    paint.setShader(shader.get());
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    current_canvas_->drawRect(quad_rect, paint);
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    current_canvas_->drawBitmapRectToRect(*bitmap,
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          &sk_uv_rect,
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          quad_rect,
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          &current_paint_);
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (needs_layer)
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    current_canvas_->restore();
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame,
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const TileDrawQuad* quad) {
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |resource_provider_| can be NULL in resourceless software draws, which
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // should never produce tile quads in the first place.
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(resource_provider_);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsSoftwareResource(quad->resource_id));
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                quad->resource_id);
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!lock.valid())
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(GL_CLAMP_TO_EDGE, lock.wrap_mode());
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_tex_coord_rect = MathUtil::ScaleRectProportional(
442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      quad->tex_coord_rect, quad->rect, quad->visible_rect);
443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      QuadVertexRect(), quad->rect, quad->visible_rect);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect);
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_paint_.setFilterLevel(SkPaint::kLow_FilterLevel);
448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  current_canvas_->drawBitmapRectToRect(
449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      *lock.sk_bitmap(),
450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      &uv_rect,
451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::RectFToSkRect(visible_quad_vertex_rect),
452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      &current_paint_);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame,
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const RenderPassDrawQuad* quad) {
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedResource* content_texture =
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_pass_textures_.get(quad->render_pass_id);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!content_texture || !content_texture->id())
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsSoftwareResource(content_texture->id()));
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                content_texture->id());
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!lock.valid())
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SkShader::TileMode content_tile_mode = WrapModeToTileMode(lock.wrap_mode());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect());
470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkRect dest_visible_rect = gfx::RectFToSkRect(MathUtil::ScaleRectProportional(
471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      QuadVertexRect(), quad->rect, quad->visible_rect));
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height());
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkMatrix content_mat;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content_mat.setRectToRect(content_rect, dest_rect,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            SkMatrix::kFill_ScaleToFit);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SkBitmap* content = lock.sk_bitmap();
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SkBitmap filter_bitmap;
4810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!quad->filters.IsEmpty()) {
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        quad->filters, content_texture->size());
4840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // TODO(ajuma): Apply the filter in the same pass as the content where
4850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // possible (e.g. when there's no origin offset). See crbug.com/308201.
4860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (filter) {
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      SkImageInfo info = SkImageInfo::MakeN32Premul(
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          content_texture->size().width(), content_texture->size().height());
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (filter_bitmap.tryAllocPixels(info)) {
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        SkCanvas canvas(filter_bitmap);
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        SkPaint paint;
492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        paint.setImageFilter(filter.get());
493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        canvas.clear(SK_ColorTRANSPARENT);
494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        canvas.translate(SkIntToScalar(-quad->rect.origin().x()),
495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         SkIntToScalar(-quad->rect.origin().y()));
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        canvas.scale(quad->filters_scale.x(), quad->filters_scale.y());
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        canvas.drawSprite(*content, 0, 0, &paint);
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  skia::RefPtr<SkShader> shader;
5030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (filter_bitmap.isNull()) {
5040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    shader = skia::AdoptRef(SkShader::CreateBitmapShader(
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        *content, content_tile_mode, content_tile_mode, &content_mat));
5060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  } else {
5070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    shader = skia::AdoptRef(SkShader::CreateBitmapShader(
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        filter_bitmap, content_tile_mode, content_tile_mode, &content_mat));
5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
5100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  current_paint_.setShader(shader.get());
5110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (quad->mask_resource_id) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ScopedReadLockSoftware mask_lock(resource_provider_,
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                       quad->mask_resource_id);
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!lock.valid())
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkShader::TileMode mask_tile_mode = WrapModeToTileMode(
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mask_lock.wrap_mode());
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SkBitmap* mask = mask_lock.sk_bitmap();
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkRect mask_rect = SkRect::MakeXYWH(
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.x() * mask->width(),
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.y() * mask->height(),
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.width() * mask->width(),
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        quad->mask_uv_rect.height() * mask->height());
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkMatrix mask_mat;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_mat.setRectToRect(mask_rect, dest_rect, SkMatrix::kFill_ScaleToFit);
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    skia::RefPtr<SkShader> mask_shader =
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        skia::AdoptRef(SkShader::CreateBitmapShader(
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            *mask, mask_tile_mode, mask_tile_mode, &mask_mat));
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPaint mask_paint;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mask_paint.setShader(mask_shader.get());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SkLayerRasterizer::Builder builder;
539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    builder.addLayer(mask_paint);
540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkLayerRasterizer> mask_rasterizer =
542c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        skia::AdoptRef(builder.detachRasterizer());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_paint_.setRasterizer(mask_rasterizer.get());
545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    current_canvas_->drawRect(dest_visible_rect, current_paint_);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(skaslev): Apply background filters
548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    current_canvas_->drawRect(dest_visible_rect, current_paint_);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame,
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const DrawQuad* quad) {
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef NDEBUG
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(SK_ColorWHITE);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setColor(SK_ColorMAGENTA);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_paint_.setAlpha(quad->opacity() * 255);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()),
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            current_paint_);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SoftwareRenderer::CopyCurrentRenderPassToBitmap(
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DrawingFrame* frame,
56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<CopyOutputRequest> request) {
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::Rect copy_rect = frame->current_render_pass->output_rect;
568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (request->has_area())
569d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    copy_rect.Intersect(request->area());
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(copy_rect);
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bitmap->setInfo(SkImageInfo::MakeN32Premul(window_copy_rect.width(),
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                             window_copy_rect.height()));
575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  current_canvas_->readPixels(
576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      bitmap.get(), window_copy_rect.x(), window_copy_rect.y());
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  request->SendBitmapResult(bitmap.Pass());
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SoftwareRenderer::DiscardBackbuffer() {
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (is_backbuffer_discarded_)
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  output_surface_->DiscardBackbuffer();
5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  is_backbuffer_discarded_ = true;
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Damage tracker needs a full reset every time framebuffer is discarded.
5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  client_->SetFullRootLayerDamage();
5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SoftwareRenderer::EnsureBackbuffer() {
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!is_backbuffer_discarded_)
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
5963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  output_surface_->EnsureBackbuffer();
5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  is_backbuffer_discarded_ = false;
5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid SoftwareRenderer::DidChangeVisibility() {
6025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (visible())
6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EnsureBackbuffer();
6043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  else
6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    DiscardBackbuffer();
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
609