OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/software_renderer.h" | 5 #include "cc/software_renderer.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "cc/debug_border_draw_quad.h" | 8 #include "cc/debug_border_draw_quad.h" |
9 #include "cc/math_util.h" | 9 #include "cc/math_util.h" |
10 #include "cc/render_pass_draw_quad.h" | 10 #include "cc/render_pass_draw_quad.h" |
11 #include "cc/software_output_device.h" | 11 #include "cc/software_output_device.h" |
12 #include "cc/solid_color_draw_quad.h" | 12 #include "cc/solid_color_draw_quad.h" |
13 #include "cc/texture_draw_quad.h" | 13 #include "cc/texture_draw_quad.h" |
14 #include "cc/tile_draw_quad.h" | 14 #include "cc/tile_draw_quad.h" |
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h" | 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h" |
16 #include "third_party/skia/include/core/SkCanvas.h" | 16 #include "third_party/skia/include/core/SkCanvas.h" |
17 #include "third_party/skia/include/core/SkColor.h" | 17 #include "third_party/skia/include/core/SkColor.h" |
| 18 #include "third_party/skia/include/core/SkDevice.h" |
18 #include "third_party/skia/include/core/SkMatrix.h" | 19 #include "third_party/skia/include/core/SkMatrix.h" |
19 #include "third_party/skia/include/core/SkShader.h" | 20 #include "third_party/skia/include/core/SkShader.h" |
20 #include "third_party/skia/include/effects/SkLayerRasterizer.h" | 21 #include "third_party/skia/include/effects/SkLayerRasterizer.h" |
21 #include "ui/gfx/rect_conversions.h" | 22 #include "ui/gfx/rect_conversions.h" |
22 #include "ui/gfx/skia_util.h" | 23 #include "ui/gfx/skia_util.h" |
23 #include "ui/gfx/transform.h" | 24 #include "ui/gfx/transform.h" |
24 | 25 |
25 namespace cc { | 26 namespace cc { |
26 | 27 |
27 namespace { | 28 namespace { |
(...skipping 24 matching lines...) Expand all Loading... |
52 } // anonymous namespace | 53 } // anonymous namespace |
53 | 54 |
54 scoped_ptr<SoftwareRenderer> SoftwareRenderer::create(RendererClient* client, Re
sourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice) | 55 scoped_ptr<SoftwareRenderer> SoftwareRenderer::create(RendererClient* client, Re
sourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice) |
55 { | 56 { |
56 return make_scoped_ptr(new SoftwareRenderer(client, resourceProvider, output
Device)); | 57 return make_scoped_ptr(new SoftwareRenderer(client, resourceProvider, output
Device)); |
57 } | 58 } |
58 | 59 |
59 SoftwareRenderer::SoftwareRenderer(RendererClient* client, ResourceProvider* res
ourceProvider, SoftwareOutputDevice* outputDevice) | 60 SoftwareRenderer::SoftwareRenderer(RendererClient* client, ResourceProvider* res
ourceProvider, SoftwareOutputDevice* outputDevice) |
60 : DirectRenderer(client, resourceProvider) | 61 : DirectRenderer(client, resourceProvider) |
61 , m_visible(true) | 62 , m_visible(true) |
| 63 , m_isScissorEnabled(false) |
62 , m_outputDevice(outputDevice) | 64 , m_outputDevice(outputDevice) |
63 , m_skCurrentCanvas(0) | 65 , m_skCurrentCanvas(0) |
64 { | 66 { |
65 m_resourceProvider->setDefaultResourceType(ResourceProvider::Bitmap); | 67 m_resourceProvider->setDefaultResourceType(ResourceProvider::Bitmap); |
66 | 68 |
67 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize(); | 69 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize(); |
68 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat(); | 70 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat(); |
69 m_capabilities.usingSetVisibility = true; | 71 m_capabilities.usingSetVisibility = true; |
70 // The updater can access bitmaps while the SoftwareRenderer is using them. | 72 // The updater can access bitmaps while the SoftwareRenderer is using them. |
71 m_capabilities.allowPartialTextureUpdates = true; | 73 m_capabilities.allowPartialTextureUpdates = true; |
| 74 m_capabilities.usingPartialSwap = true; |
72 | 75 |
73 viewportChanged(); | 76 viewportChanged(); |
74 } | 77 } |
75 | 78 |
76 SoftwareRenderer::~SoftwareRenderer() | 79 SoftwareRenderer::~SoftwareRenderer() |
77 { | 80 { |
78 } | 81 } |
79 | 82 |
80 const RendererCapabilities& SoftwareRenderer::capabilities() const | 83 const RendererCapabilities& SoftwareRenderer::capabilities() const |
81 { | 84 { |
(...skipping 20 matching lines...) Expand all Loading... |
102 m_outputDevice->Unlock(); | 105 m_outputDevice->Unlock(); |
103 } | 106 } |
104 | 107 |
105 bool SoftwareRenderer::flippedFramebuffer() const | 108 bool SoftwareRenderer::flippedFramebuffer() const |
106 { | 109 { |
107 return false; | 110 return false; |
108 } | 111 } |
109 | 112 |
110 void SoftwareRenderer::ensureScissorTestEnabled() | 113 void SoftwareRenderer::ensureScissorTestEnabled() |
111 { | 114 { |
112 // Nothing to do here. Current implementation of software rendering has no | 115 m_isScissorEnabled = true; |
113 // notion of enabling/disabling the feature. | 116 setClipRect(m_scissorRect); |
114 } | 117 } |
115 | 118 |
116 void SoftwareRenderer::ensureScissorTestDisabled() | 119 void SoftwareRenderer::ensureScissorTestDisabled() |
117 { | 120 { |
118 // There is no explicit notion of enabling/disabling scissoring in software | 121 // There is no explicit notion of enabling/disabling scissoring in software |
119 // rendering, but the underlying effect we want is to clear any existing | 122 // rendering, but the underlying effect we want is to clear any existing |
120 // clipRect on the current SkCanvas. This is done by setting clipRect to | 123 // clipRect on the current SkCanvas. This is done by setting clipRect to |
121 // the viewport's dimensions. | 124 // the viewport's dimensions. |
122 SkISize canvasSize = m_skCurrentCanvas->getDeviceSize(); | 125 m_isScissorEnabled = false; |
123 SkRect canvasRect = SkRect::MakeXYWH(0, 0, canvasSize.width(), canvasSize.he
ight()); | 126 SkDevice* device = m_skCurrentCanvas->getDevice(); |
124 m_skCurrentCanvas->clipRect(canvasRect, SkRegion::kReplace_Op); | 127 setClipRect(gfx::Rect(device->width(), device->height())); |
125 } | 128 } |
126 | 129 |
127 void SoftwareRenderer::finish() | 130 void SoftwareRenderer::finish() |
128 { | 131 { |
129 } | 132 } |
130 | 133 |
131 void SoftwareRenderer::bindFramebufferToOutputSurface(DrawingFrame& frame) | 134 void SoftwareRenderer::bindFramebufferToOutputSurface(DrawingFrame& frame) |
132 { | 135 { |
133 m_currentFramebufferLock.reset(); | 136 m_currentFramebufferLock.reset(); |
134 m_skCurrentCanvas = m_skRootCanvas.get(); | 137 m_skCurrentCanvas = m_skRootCanvas.get(); |
135 } | 138 } |
136 | 139 |
137 bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const Scope
dResource* texture, const gfx::Rect& framebufferRect) | 140 bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const Scope
dResource* texture, const gfx::Rect& framebufferRect) |
138 { | 141 { |
139 m_currentFramebufferLock = make_scoped_ptr(new ResourceProvider::ScopedWrite
LockSoftware(m_resourceProvider, texture->id())); | 142 m_currentFramebufferLock = make_scoped_ptr(new ResourceProvider::ScopedWrite
LockSoftware(m_resourceProvider, texture->id())); |
140 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas(); | 143 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas(); |
141 initializeMatrices(frame, framebufferRect, false); | 144 initializeMatrices(frame, framebufferRect, false); |
142 setDrawViewportSize(framebufferRect.size()); | 145 setDrawViewportSize(framebufferRect.size()); |
143 | 146 |
144 return true; | 147 return true; |
145 } | 148 } |
146 | 149 |
147 void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect) | 150 void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect) |
148 { | 151 { |
149 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(scissorRect), SkRegion::kRepla
ce_Op); | 152 m_isScissorEnabled = true; |
| 153 m_scissorRect = scissorRect; |
| 154 setClipRect(scissorRect); |
| 155 } |
| 156 |
| 157 void SoftwareRenderer::setClipRect(const gfx::Rect& rect) |
| 158 { |
| 159 // Skia applies the current matrix to clip rects so we reset it temporary. |
| 160 SkMatrix currentMatrix = m_skCurrentCanvas->getTotalMatrix(); |
| 161 m_skCurrentCanvas->resetMatrix(); |
| 162 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(rect), SkRegion::kReplace_Op); |
| 163 m_skCurrentCanvas->setMatrix(currentMatrix); |
| 164 } |
| 165 |
| 166 void SoftwareRenderer::clearCanvas(SkColor color) |
| 167 { |
| 168 // SkCanvas::clear doesn't respect the current clipping region |
| 169 // so we SkCanvas::drawColor instead if scissoring is active. |
| 170 if (m_isScissorEnabled) |
| 171 m_skCurrentCanvas->drawColor(color, SkXfermode::kSrc_Mode); |
| 172 else |
| 173 m_skCurrentCanvas->clear(color); |
150 } | 174 } |
151 | 175 |
152 void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame) | 176 void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame) |
153 { | 177 { |
154 if (frame.currentRenderPass->has_transparent_background) { | 178 if (frame.currentRenderPass->has_transparent_background) { |
155 m_skCurrentCanvas->clear(SkColorSetARGB(0, 0, 0, 0)); | 179 clearCanvas(SkColorSetARGB(0, 0, 0, 0)); |
156 } else { | 180 } else { |
157 #ifndef NDEBUG | 181 #ifndef NDEBUG |
158 // On DEBUG builds, opaque render passes are cleared to blue to easily s
ee regions that were not drawn on the screen. | 182 // On DEBUG builds, opaque render passes are cleared to blue to easily s
ee regions that were not drawn on the screen. |
159 m_skCurrentCanvas->clear(SkColorSetARGB(255, 0, 0, 255)); | 183 clearCanvas(SkColorSetARGB(255, 0, 0, 255)); |
160 #endif | 184 #endif |
161 } | 185 } |
162 } | 186 } |
163 | 187 |
164 void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize) | 188 void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize) |
165 { | 189 { |
166 } | 190 } |
167 | 191 |
168 bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const | 192 bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const |
169 { | 193 { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const Rende
rPassDrawQuad* quad) | 309 void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const Rende
rPassDrawQuad* quad) |
286 { | 310 { |
287 CachedResource* contentTexture = m_renderPassTextures.get(quad->render_pass_
id); | 311 CachedResource* contentTexture = m_renderPassTextures.get(quad->render_pass_
id); |
288 if (!contentTexture || !contentTexture->id()) | 312 if (!contentTexture || !contentTexture->id()) |
289 return; | 313 return; |
290 | 314 |
291 DCHECK(isSoftwareResource(contentTexture->id())); | 315 DCHECK(isSoftwareResource(contentTexture->id())); |
292 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTex
ture->id()); | 316 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTex
ture->id()); |
293 | 317 |
294 SkRect destRect = gfx::RectFToSkRect(quadVertexRect()); | 318 SkRect destRect = gfx::RectFToSkRect(quadVertexRect()); |
295 | 319 SkRect contentRect = SkRect::MakeWH(quad->rect.width(), quad->rect.height())
; |
296 const SkBitmap* content = lock.skBitmap(); | |
297 | |
298 SkRect contentRect; | |
299 content->getBounds(&contentRect); | |
300 | 320 |
301 SkMatrix contentMat; | 321 SkMatrix contentMat; |
302 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit); | 322 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit); |
303 | 323 |
| 324 const SkBitmap* content = lock.skBitmap(); |
304 skia::RefPtr<SkShader> shader = skia::AdoptRef( | 325 skia::RefPtr<SkShader> shader = skia::AdoptRef( |
305 SkShader::CreateBitmapShader(*content, | 326 SkShader::CreateBitmapShader(*content, |
306 SkShader::kClamp_TileMode, | 327 SkShader::kClamp_TileMode, |
307 SkShader::kClamp_TileMode)); | 328 SkShader::kClamp_TileMode)); |
308 shader->setLocalMatrix(contentMat); | 329 shader->setLocalMatrix(contentMat); |
309 m_skCurrentPaint.setShader(shader.get()); | 330 m_skCurrentPaint.setShader(shader.get()); |
310 | 331 |
311 SkImageFilter* filter = quad->filter.get(); | 332 SkImageFilter* filter = quad->filter.get(); |
312 if (filter) | 333 if (filter) |
313 m_skCurrentPaint.setImageFilter(filter); | 334 m_skCurrentPaint.setImageFilter(filter); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 393 } |
373 | 394 |
374 void SoftwareRenderer::setVisible(bool visible) | 395 void SoftwareRenderer::setVisible(bool visible) |
375 { | 396 { |
376 if (m_visible == visible) | 397 if (m_visible == visible) |
377 return; | 398 return; |
378 m_visible = visible; | 399 m_visible = visible; |
379 } | 400 } |
380 | 401 |
381 } // namespace cc | 402 } // namespace cc |
OLD | NEW |