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, ¤t_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) ¤t_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) ¤t_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