| 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/output/software_renderer.h" | 5 #include "cc/output/software_renderer.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
| 10 #include "cc/output/copy_output_request.h" | 10 #include "cc/output/copy_output_request.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 SoftwareRenderer::~SoftwareRenderer() {} | 62 SoftwareRenderer::~SoftwareRenderer() {} |
| 63 | 63 |
| 64 bool SoftwareRenderer::CanPartialSwap() { | 64 bool SoftwareRenderer::CanPartialSwap() { |
| 65 return true; | 65 return true; |
| 66 } | 66 } |
| 67 | 67 |
| 68 ResourceFormat SoftwareRenderer::BackbufferFormat() const { | 68 ResourceFormat SoftwareRenderer::BackbufferFormat() const { |
| 69 return resource_provider_->best_texture_format(); | 69 return resource_provider_->best_texture_format(); |
| 70 } | 70 } |
| 71 | 71 |
| 72 void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) { | 72 void SoftwareRenderer::BeginDrawingFrame() { |
| 73 TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame"); | 73 TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame"); |
| 74 root_canvas_ = output_device_->BeginPaint(frame->root_damage_rect); | 74 root_canvas_ = output_device_->BeginPaint(current_frame()->root_damage_rect); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) { | 77 void SoftwareRenderer::FinishDrawingFrame() { |
| 78 TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame"); | 78 TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame"); |
| 79 current_framebuffer_lock_ = nullptr; | 79 current_framebuffer_lock_ = nullptr; |
| 80 current_framebuffer_canvas_.reset(); | 80 current_framebuffer_canvas_.reset(); |
| 81 current_canvas_ = nullptr; | 81 current_canvas_ = nullptr; |
| 82 root_canvas_ = nullptr; | 82 root_canvas_ = nullptr; |
| 83 | 83 |
| 84 output_device_->EndPaint(); | 84 output_device_->EndPaint(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void SoftwareRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { | 87 void SoftwareRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { |
| 88 DCHECK(visible_); | 88 DCHECK(visible_); |
| 89 TRACE_EVENT0("cc", "SoftwareRenderer::SwapBuffers"); | 89 TRACE_EVENT0("cc", "SoftwareRenderer::SwapBuffers"); |
| 90 OutputSurfaceFrame output_frame; | 90 OutputSurfaceFrame output_frame; |
| 91 output_frame.latency_info = std::move(latency_info); | 91 output_frame.latency_info = std::move(latency_info); |
| 92 output_surface_->SwapBuffers(std::move(output_frame)); | 92 output_surface_->SwapBuffers(std::move(output_frame)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool SoftwareRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { | 95 bool SoftwareRenderer::FlippedFramebuffer() const { |
| 96 return false; | 96 return false; |
| 97 } | 97 } |
| 98 | 98 |
| 99 void SoftwareRenderer::EnsureScissorTestEnabled() { | 99 void SoftwareRenderer::EnsureScissorTestEnabled() { |
| 100 is_scissor_enabled_ = true; | 100 is_scissor_enabled_ = true; |
| 101 SetClipRect(scissor_rect_); | 101 SetClipRect(scissor_rect_); |
| 102 } | 102 } |
| 103 | 103 |
| 104 void SoftwareRenderer::EnsureScissorTestDisabled() { | 104 void SoftwareRenderer::EnsureScissorTestDisabled() { |
| 105 // There is no explicit notion of enabling/disabling scissoring in software | 105 // There is no explicit notion of enabling/disabling scissoring in software |
| 106 // rendering, but the underlying effect we want is to clear any existing | 106 // rendering, but the underlying effect we want is to clear any existing |
| 107 // clipRect on the current SkCanvas. This is done by setting clipRect to | 107 // clipRect on the current SkCanvas. This is done by setting clipRect to |
| 108 // the viewport's dimensions. | 108 // the viewport's dimensions. |
| 109 if (!current_canvas_) | 109 if (!current_canvas_) |
| 110 return; | 110 return; |
| 111 is_scissor_enabled_ = false; | 111 is_scissor_enabled_ = false; |
| 112 SkISize size = current_canvas_->getBaseLayerSize(); | 112 SkISize size = current_canvas_->getBaseLayerSize(); |
| 113 SetClipRect(gfx::Rect(size.width(), size.height())); | 113 SetClipRect(gfx::Rect(size.width(), size.height())); |
| 114 } | 114 } |
| 115 | 115 |
| 116 void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { | 116 void SoftwareRenderer::BindFramebufferToOutputSurface() { |
| 117 DCHECK(!output_surface_->HasExternalStencilTest()); | 117 DCHECK(!output_surface_->HasExternalStencilTest()); |
| 118 current_framebuffer_lock_ = nullptr; | 118 current_framebuffer_lock_ = nullptr; |
| 119 current_framebuffer_canvas_.reset(); | 119 current_framebuffer_canvas_.reset(); |
| 120 current_canvas_ = root_canvas_; | 120 current_canvas_ = root_canvas_; |
| 121 } | 121 } |
| 122 | 122 |
| 123 bool SoftwareRenderer::BindFramebufferToTexture( | 123 bool SoftwareRenderer::BindFramebufferToTexture( |
| 124 DrawingFrame* frame, | |
| 125 const ScopedResource* texture) { | 124 const ScopedResource* texture) { |
| 126 DCHECK(texture->id()); | 125 DCHECK(texture->id()); |
| 127 | 126 |
| 128 // Explicitly release lock, otherwise we can crash when try to lock | 127 // Explicitly release lock, otherwise we can crash when try to lock |
| 129 // same texture again. | 128 // same texture again. |
| 130 current_framebuffer_lock_ = nullptr; | 129 current_framebuffer_lock_ = nullptr; |
| 131 current_framebuffer_lock_ = | 130 current_framebuffer_lock_ = |
| 132 base::MakeUnique<ResourceProvider::ScopedWriteLockSoftware>( | 131 base::MakeUnique<ResourceProvider::ScopedWriteLockSoftware>( |
| 133 resource_provider_, texture->id()); | 132 resource_provider_, texture->id()); |
| 134 current_framebuffer_canvas_ = | 133 current_framebuffer_canvas_ = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 154 SkClipOp::kReplace_private_internal_do_not_use); | 153 SkClipOp::kReplace_private_internal_do_not_use); |
| 155 current_canvas_->setMatrix(current_matrix); | 154 current_canvas_->setMatrix(current_matrix); |
| 156 } | 155 } |
| 157 | 156 |
| 158 void SoftwareRenderer::ClearCanvas(SkColor color) { | 157 void SoftwareRenderer::ClearCanvas(SkColor color) { |
| 159 if (!current_canvas_) | 158 if (!current_canvas_) |
| 160 return; | 159 return; |
| 161 current_canvas_->clear(color); | 160 current_canvas_->clear(color); |
| 162 } | 161 } |
| 163 | 162 |
| 164 void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) { | 163 void SoftwareRenderer::ClearFramebuffer() { |
| 165 if (frame->current_render_pass->has_transparent_background) { | 164 if (current_frame()->current_render_pass->has_transparent_background) { |
| 166 ClearCanvas(SkColorSetARGB(0, 0, 0, 0)); | 165 ClearCanvas(SkColorSetARGB(0, 0, 0, 0)); |
| 167 } else { | 166 } else { |
| 168 #ifndef NDEBUG | 167 #ifndef NDEBUG |
| 169 // On DEBUG builds, opaque render passes are cleared to blue | 168 // On DEBUG builds, opaque render passes are cleared to blue |
| 170 // to easily see regions that were not drawn on the screen. | 169 // to easily see regions that were not drawn on the screen. |
| 171 ClearCanvas(SkColorSetARGB(255, 0, 0, 255)); | 170 ClearCanvas(SkColorSetARGB(255, 0, 0, 255)); |
| 172 #endif | 171 #endif |
| 173 } | 172 } |
| 174 } | 173 } |
| 175 | 174 |
| 176 void SoftwareRenderer::PrepareSurfaceForPass( | 175 void SoftwareRenderer::PrepareSurfaceForPass( |
| 177 DrawingFrame* frame, | |
| 178 SurfaceInitializationMode initialization_mode, | 176 SurfaceInitializationMode initialization_mode, |
| 179 const gfx::Rect& render_pass_scissor) { | 177 const gfx::Rect& render_pass_scissor) { |
| 180 switch (initialization_mode) { | 178 switch (initialization_mode) { |
| 181 case SURFACE_INITIALIZATION_MODE_PRESERVE: | 179 case SURFACE_INITIALIZATION_MODE_PRESERVE: |
| 182 EnsureScissorTestDisabled(); | 180 EnsureScissorTestDisabled(); |
| 183 return; | 181 return; |
| 184 case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR: | 182 case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR: |
| 185 EnsureScissorTestDisabled(); | 183 EnsureScissorTestDisabled(); |
| 186 ClearFramebuffer(frame); | 184 ClearFramebuffer(); |
| 187 break; | 185 break; |
| 188 case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR: | 186 case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR: |
| 189 SetScissorTestRect(render_pass_scissor); | 187 SetScissorTestRect(render_pass_scissor); |
| 190 ClearFramebuffer(frame); | 188 ClearFramebuffer(); |
| 191 break; | 189 break; |
| 192 } | 190 } |
| 193 } | 191 } |
| 194 | 192 |
| 195 bool SoftwareRenderer::IsSoftwareResource(ResourceId resource_id) const { | 193 bool SoftwareRenderer::IsSoftwareResource(ResourceId resource_id) const { |
| 196 switch (resource_provider_->GetResourceType(resource_id)) { | 194 switch (resource_provider_->GetResourceType(resource_id)) { |
| 197 case ResourceProvider::RESOURCE_TYPE_GPU_MEMORY_BUFFER: | 195 case ResourceProvider::RESOURCE_TYPE_GPU_MEMORY_BUFFER: |
| 198 case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: | 196 case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: |
| 199 return false; | 197 return false; |
| 200 case ResourceProvider::RESOURCE_TYPE_BITMAP: | 198 case ResourceProvider::RESOURCE_TYPE_BITMAP: |
| 201 return true; | 199 return true; |
| 202 } | 200 } |
| 203 | 201 |
| 204 LOG(FATAL) << "Invalid resource type."; | 202 LOG(FATAL) << "Invalid resource type."; |
| 205 return false; | 203 return false; |
| 206 } | 204 } |
| 207 | 205 |
| 208 void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, | 206 void SoftwareRenderer::DoDrawQuad(const DrawQuad* quad, |
| 209 const DrawQuad* quad, | |
| 210 const gfx::QuadF* draw_region) { | 207 const gfx::QuadF* draw_region) { |
| 211 if (!current_canvas_) | 208 if (!current_canvas_) |
| 212 return; | 209 return; |
| 213 if (draw_region) { | 210 if (draw_region) { |
| 214 current_canvas_->save(); | 211 current_canvas_->save(); |
| 215 } | 212 } |
| 216 | 213 |
| 217 TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad"); | 214 TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad"); |
| 218 gfx::Transform quad_rect_matrix; | 215 gfx::Transform quad_rect_matrix; |
| 219 QuadRectTransform(&quad_rect_matrix, | 216 QuadRectTransform(&quad_rect_matrix, |
| 220 quad->shared_quad_state->quad_to_target_transform, | 217 quad->shared_quad_state->quad_to_target_transform, |
| 221 gfx::RectF(quad->rect)); | 218 gfx::RectF(quad->rect)); |
| 222 gfx::Transform contents_device_transform = | 219 gfx::Transform contents_device_transform = |
| 223 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 220 current_frame()->window_matrix * current_frame()->projection_matrix * |
| 221 quad_rect_matrix; |
| 224 contents_device_transform.FlattenTo2d(); | 222 contents_device_transform.FlattenTo2d(); |
| 225 SkMatrix sk_device_matrix; | 223 SkMatrix sk_device_matrix; |
| 226 gfx::TransformToFlattenedSkMatrix(contents_device_transform, | 224 gfx::TransformToFlattenedSkMatrix(contents_device_transform, |
| 227 &sk_device_matrix); | 225 &sk_device_matrix); |
| 228 current_canvas_->setMatrix(sk_device_matrix); | 226 current_canvas_->setMatrix(sk_device_matrix); |
| 229 | 227 |
| 230 current_paint_.reset(); | 228 current_paint_.reset(); |
| 231 if (settings_->force_antialiasing || | 229 if (settings_->force_antialiasing || |
| 232 !IsScaleAndIntegerTranslate(sk_device_matrix)) { | 230 !IsScaleAndIntegerTranslate(sk_device_matrix)) { |
| 233 // TODO(danakj): Until we can enable AA only on exterior edges of the | 231 // TODO(danakj): Until we can enable AA only on exterior edges of the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 261 | 259 |
| 262 SkPoint clip_points[4]; | 260 SkPoint clip_points[4]; |
| 263 QuadFToSkPoints(local_draw_region, clip_points); | 261 QuadFToSkPoints(local_draw_region, clip_points); |
| 264 draw_region_clip_path.addPoly(clip_points, 4, true); | 262 draw_region_clip_path.addPoly(clip_points, 4, true); |
| 265 | 263 |
| 266 current_canvas_->clipPath(draw_region_clip_path); | 264 current_canvas_->clipPath(draw_region_clip_path); |
| 267 } | 265 } |
| 268 | 266 |
| 269 switch (quad->material) { | 267 switch (quad->material) { |
| 270 case DrawQuad::DEBUG_BORDER: | 268 case DrawQuad::DEBUG_BORDER: |
| 271 DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad)); | 269 DrawDebugBorderQuad(DebugBorderDrawQuad::MaterialCast(quad)); |
| 272 break; | 270 break; |
| 273 case DrawQuad::PICTURE_CONTENT: | 271 case DrawQuad::PICTURE_CONTENT: |
| 274 DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad)); | 272 DrawPictureQuad(PictureDrawQuad::MaterialCast(quad)); |
| 275 break; | 273 break; |
| 276 case DrawQuad::RENDER_PASS: | 274 case DrawQuad::RENDER_PASS: |
| 277 DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad)); | 275 DrawRenderPassQuad(RenderPassDrawQuad::MaterialCast(quad)); |
| 278 break; | 276 break; |
| 279 case DrawQuad::SOLID_COLOR: | 277 case DrawQuad::SOLID_COLOR: |
| 280 DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad)); | 278 DrawSolidColorQuad(SolidColorDrawQuad::MaterialCast(quad)); |
| 281 break; | 279 break; |
| 282 case DrawQuad::TEXTURE_CONTENT: | 280 case DrawQuad::TEXTURE_CONTENT: |
| 283 DrawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad)); | 281 DrawTextureQuad(TextureDrawQuad::MaterialCast(quad)); |
| 284 break; | 282 break; |
| 285 case DrawQuad::TILED_CONTENT: | 283 case DrawQuad::TILED_CONTENT: |
| 286 DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad)); | 284 DrawTileQuad(TileDrawQuad::MaterialCast(quad)); |
| 287 break; | 285 break; |
| 288 case DrawQuad::SURFACE_CONTENT: | 286 case DrawQuad::SURFACE_CONTENT: |
| 289 // Surface content should be fully resolved to other quad types before | 287 // Surface content should be fully resolved to other quad types before |
| 290 // reaching a direct renderer. | 288 // reaching a direct renderer. |
| 291 NOTREACHED(); | 289 NOTREACHED(); |
| 292 break; | 290 break; |
| 293 case DrawQuad::INVALID: | 291 case DrawQuad::INVALID: |
| 294 case DrawQuad::YUV_VIDEO_CONTENT: | 292 case DrawQuad::YUV_VIDEO_CONTENT: |
| 295 case DrawQuad::STREAM_VIDEO_CONTENT: | 293 case DrawQuad::STREAM_VIDEO_CONTENT: |
| 296 DrawUnsupportedQuad(frame, quad); | 294 DrawUnsupportedQuad(quad); |
| 297 NOTREACHED(); | 295 NOTREACHED(); |
| 298 break; | 296 break; |
| 299 } | 297 } |
| 300 | 298 |
| 301 current_canvas_->resetMatrix(); | 299 current_canvas_->resetMatrix(); |
| 302 if (draw_region) { | 300 if (draw_region) { |
| 303 current_canvas_->restore(); | 301 current_canvas_->restore(); |
| 304 } | 302 } |
| 305 } | 303 } |
| 306 | 304 |
| 307 void SoftwareRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, | 305 void SoftwareRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { |
| 308 const DebugBorderDrawQuad* quad) { | |
| 309 // We need to apply the matrix manually to have pixel-sized stroke width. | 306 // We need to apply the matrix manually to have pixel-sized stroke width. |
| 310 SkPoint vertices[4]; | 307 SkPoint vertices[4]; |
| 311 gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); | 308 gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); |
| 312 SkPoint transformed_vertices[4]; | 309 SkPoint transformed_vertices[4]; |
| 313 current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, | 310 current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, |
| 314 vertices, | 311 vertices, |
| 315 4); | 312 4); |
| 316 current_canvas_->resetMatrix(); | 313 current_canvas_->resetMatrix(); |
| 317 | 314 |
| 318 current_paint_.setColor(quad->color); | 315 current_paint_.setColor(quad->color); |
| 319 current_paint_.setAlpha(quad->shared_quad_state->opacity * | 316 current_paint_.setAlpha(quad->shared_quad_state->opacity * |
| 320 SkColorGetA(quad->color)); | 317 SkColorGetA(quad->color)); |
| 321 current_paint_.setStyle(SkPaint::kStroke_Style); | 318 current_paint_.setStyle(SkPaint::kStroke_Style); |
| 322 current_paint_.setStrokeWidth(quad->width); | 319 current_paint_.setStrokeWidth(quad->width); |
| 323 current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode, | 320 current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode, |
| 324 4, transformed_vertices, current_paint_); | 321 4, transformed_vertices, current_paint_); |
| 325 } | 322 } |
| 326 | 323 |
| 327 void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, | 324 void SoftwareRenderer::DrawPictureQuad(const PictureDrawQuad* quad) { |
| 328 const PictureDrawQuad* quad) { | |
| 329 SkMatrix content_matrix; | 325 SkMatrix content_matrix; |
| 330 content_matrix.setRectToRect( | 326 content_matrix.setRectToRect( |
| 331 gfx::RectFToSkRect(quad->tex_coord_rect), | 327 gfx::RectFToSkRect(quad->tex_coord_rect), |
| 332 gfx::RectFToSkRect(QuadVertexRect()), | 328 gfx::RectFToSkRect(QuadVertexRect()), |
| 333 SkMatrix::kFill_ScaleToFit); | 329 SkMatrix::kFill_ScaleToFit); |
| 334 current_canvas_->concat(content_matrix); | 330 current_canvas_->concat(content_matrix); |
| 335 | 331 |
| 336 const bool needs_transparency = | 332 const bool needs_transparency = |
| 337 SkScalarRoundToInt(quad->shared_quad_state->opacity * 255) < 255; | 333 SkScalarRoundToInt(quad->shared_quad_state->opacity * 255) < 255; |
| 338 const bool disable_image_filtering = | 334 const bool disable_image_filtering = |
| (...skipping 23 matching lines...) Expand all Loading... |
| 362 quad->raster_source->PlaybackToCanvas( | 358 quad->raster_source->PlaybackToCanvas( |
| 363 &filtered_canvas, quad->content_rect, quad->content_rect, | 359 &filtered_canvas, quad->content_rect, quad->content_rect, |
| 364 quad->contents_scale, playback_settings); | 360 quad->contents_scale, playback_settings); |
| 365 } else { | 361 } else { |
| 366 quad->raster_source->PlaybackToCanvas( | 362 quad->raster_source->PlaybackToCanvas( |
| 367 current_canvas_, quad->content_rect, quad->content_rect, | 363 current_canvas_, quad->content_rect, quad->content_rect, |
| 368 quad->contents_scale, playback_settings); | 364 quad->contents_scale, playback_settings); |
| 369 } | 365 } |
| 370 } | 366 } |
| 371 | 367 |
| 372 void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame, | 368 void SoftwareRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad) { |
| 373 const SolidColorDrawQuad* quad) { | |
| 374 gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional( | 369 gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional( |
| 375 QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); | 370 QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); |
| 376 current_paint_.setColor(quad->color); | 371 current_paint_.setColor(quad->color); |
| 377 current_paint_.setAlpha(quad->shared_quad_state->opacity * | 372 current_paint_.setAlpha(quad->shared_quad_state->opacity * |
| 378 SkColorGetA(quad->color)); | 373 SkColorGetA(quad->color)); |
| 379 current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect), | 374 current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect), |
| 380 current_paint_); | 375 current_paint_); |
| 381 } | 376 } |
| 382 | 377 |
| 383 void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame, | 378 void SoftwareRenderer::DrawTextureQuad(const TextureDrawQuad* quad) { |
| 384 const TextureDrawQuad* quad) { | |
| 385 if (!IsSoftwareResource(quad->resource_id())) { | 379 if (!IsSoftwareResource(quad->resource_id())) { |
| 386 DrawUnsupportedQuad(frame, quad); | 380 DrawUnsupportedQuad(quad); |
| 387 return; | 381 return; |
| 388 } | 382 } |
| 389 | 383 |
| 390 // TODO(skaslev): Add support for non-premultiplied alpha. | 384 // TODO(skaslev): Add support for non-premultiplied alpha. |
| 391 ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, | 385 ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, |
| 392 quad->resource_id()); | 386 quad->resource_id()); |
| 393 if (!lock.valid()) | 387 if (!lock.valid()) |
| 394 return; | 388 return; |
| 395 const SkImage* image = lock.sk_image(); | 389 const SkImage* image = lock.sk_image(); |
| 396 gfx::RectF uv_rect = gfx::ScaleRect( | 390 gfx::RectF uv_rect = gfx::ScaleRect( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 418 background_paint.setColor(quad->background_color); | 412 background_paint.setColor(quad->background_color); |
| 419 current_canvas_->drawRect(quad_rect, background_paint); | 413 current_canvas_->drawRect(quad_rect, background_paint); |
| 420 } | 414 } |
| 421 current_paint_.setFilterQuality( | 415 current_paint_.setFilterQuality( |
| 422 quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); | 416 quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); |
| 423 current_canvas_->drawImageRect(image, sk_uv_rect, quad_rect, ¤t_paint_); | 417 current_canvas_->drawImageRect(image, sk_uv_rect, quad_rect, ¤t_paint_); |
| 424 if (needs_layer) | 418 if (needs_layer) |
| 425 current_canvas_->restore(); | 419 current_canvas_->restore(); |
| 426 } | 420 } |
| 427 | 421 |
| 428 void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame, | 422 void SoftwareRenderer::DrawTileQuad(const TileDrawQuad* quad) { |
| 429 const TileDrawQuad* quad) { | |
| 430 // |resource_provider_| can be NULL in resourceless software draws, which | 423 // |resource_provider_| can be NULL in resourceless software draws, which |
| 431 // should never produce tile quads in the first place. | 424 // should never produce tile quads in the first place. |
| 432 DCHECK(resource_provider_); | 425 DCHECK(resource_provider_); |
| 433 DCHECK(IsSoftwareResource(quad->resource_id())); | 426 DCHECK(IsSoftwareResource(quad->resource_id())); |
| 434 | 427 |
| 435 ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, | 428 ResourceProvider::ScopedReadLockSkImage lock(resource_provider_, |
| 436 quad->resource_id()); | 429 quad->resource_id()); |
| 437 if (!lock.valid()) | 430 if (!lock.valid()) |
| 438 return; | 431 return; |
| 439 | 432 |
| 440 gfx::RectF visible_tex_coord_rect = MathUtil::ScaleRectProportional( | 433 gfx::RectF visible_tex_coord_rect = MathUtil::ScaleRectProportional( |
| 441 quad->tex_coord_rect, gfx::RectF(quad->rect), | 434 quad->tex_coord_rect, gfx::RectF(quad->rect), |
| 442 gfx::RectF(quad->visible_rect)); | 435 gfx::RectF(quad->visible_rect)); |
| 443 gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional( | 436 gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional( |
| 444 QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); | 437 QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect)); |
| 445 | 438 |
| 446 SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect); | 439 SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect); |
| 447 current_paint_.setFilterQuality( | 440 current_paint_.setFilterQuality( |
| 448 quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); | 441 quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); |
| 449 current_canvas_->drawImageRect(lock.sk_image(), uv_rect, | 442 current_canvas_->drawImageRect(lock.sk_image(), uv_rect, |
| 450 gfx::RectFToSkRect(visible_quad_vertex_rect), | 443 gfx::RectFToSkRect(visible_quad_vertex_rect), |
| 451 ¤t_paint_); | 444 ¤t_paint_); |
| 452 } | 445 } |
| 453 | 446 |
| 454 void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame, | 447 void SoftwareRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad) { |
| 455 const RenderPassDrawQuad* quad) { | |
| 456 ScopedResource* content_texture = | 448 ScopedResource* content_texture = |
| 457 render_pass_textures_[quad->render_pass_id].get(); | 449 render_pass_textures_[quad->render_pass_id].get(); |
| 458 DCHECK(content_texture); | 450 DCHECK(content_texture); |
| 459 DCHECK(content_texture->id()); | 451 DCHECK(content_texture->id()); |
| 460 DCHECK(IsSoftwareResource(content_texture->id())); | 452 DCHECK(IsSoftwareResource(content_texture->id())); |
| 461 | 453 |
| 462 ResourceProvider::ScopedReadLockSoftware lock(resource_provider_, | 454 ResourceProvider::ScopedReadLockSoftware lock(resource_provider_, |
| 463 content_texture->id()); | 455 content_texture->id()); |
| 464 if (!lock.valid()) | 456 if (!lock.valid()) |
| 465 return; | 457 return; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 SkShader::kClamp_TileMode, &mask_mat)); | 530 SkShader::kClamp_TileMode, &mask_mat)); |
| 539 | 531 |
| 540 SkLayerRasterizer::Builder builder; | 532 SkLayerRasterizer::Builder builder; |
| 541 builder.addLayer(mask_paint); | 533 builder.addLayer(mask_paint); |
| 542 | 534 |
| 543 current_paint_.setRasterizer(builder.detach()); | 535 current_paint_.setRasterizer(builder.detach()); |
| 544 } | 536 } |
| 545 | 537 |
| 546 // If we have a background filter shader, render its results first. | 538 // If we have a background filter shader, render its results first. |
| 547 sk_sp<SkShader> background_filter_shader = | 539 sk_sp<SkShader> background_filter_shader = |
| 548 GetBackgroundFilterShader(frame, quad, SkShader::kClamp_TileMode); | 540 GetBackgroundFilterShader(quad, SkShader::kClamp_TileMode); |
| 549 if (background_filter_shader) { | 541 if (background_filter_shader) { |
| 550 SkPaint paint; | 542 SkPaint paint; |
| 551 paint.setShader(std::move(background_filter_shader)); | 543 paint.setShader(std::move(background_filter_shader)); |
| 552 paint.setRasterizer(current_paint_.refRasterizer()); | 544 paint.setRasterizer(current_paint_.refRasterizer()); |
| 553 current_canvas_->drawRect(dest_visible_rect, paint); | 545 current_canvas_->drawRect(dest_visible_rect, paint); |
| 554 } | 546 } |
| 555 current_paint_.setShader(std::move(shader)); | 547 current_paint_.setShader(std::move(shader)); |
| 556 current_canvas_->drawRect(dest_visible_rect, current_paint_); | 548 current_canvas_->drawRect(dest_visible_rect, current_paint_); |
| 557 } | 549 } |
| 558 | 550 |
| 559 void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame, | 551 void SoftwareRenderer::DrawUnsupportedQuad(const DrawQuad* quad) { |
| 560 const DrawQuad* quad) { | |
| 561 #ifdef NDEBUG | 552 #ifdef NDEBUG |
| 562 current_paint_.setColor(SK_ColorWHITE); | 553 current_paint_.setColor(SK_ColorWHITE); |
| 563 #else | 554 #else |
| 564 current_paint_.setColor(SK_ColorMAGENTA); | 555 current_paint_.setColor(SK_ColorMAGENTA); |
| 565 #endif | 556 #endif |
| 566 current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); | 557 current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); |
| 567 current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()), | 558 current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()), |
| 568 current_paint_); | 559 current_paint_); |
| 569 } | 560 } |
| 570 | 561 |
| 571 void SoftwareRenderer::CopyCurrentRenderPassToBitmap( | 562 void SoftwareRenderer::CopyCurrentRenderPassToBitmap( |
| 572 DrawingFrame* frame, | |
| 573 std::unique_ptr<CopyOutputRequest> request) { | 563 std::unique_ptr<CopyOutputRequest> request) { |
| 574 gfx::Rect copy_rect = frame->current_render_pass->output_rect; | 564 gfx::Rect copy_rect = current_frame()->current_render_pass->output_rect; |
| 575 if (request->has_area()) | 565 if (request->has_area()) |
| 576 copy_rect.Intersect(request->area()); | 566 copy_rect.Intersect(request->area()); |
| 577 gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(frame, copy_rect); | 567 gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(copy_rect); |
| 578 | 568 |
| 579 std::unique_ptr<SkBitmap> bitmap(new SkBitmap); | 569 std::unique_ptr<SkBitmap> bitmap(new SkBitmap); |
| 580 bitmap->setInfo(SkImageInfo::MakeN32Premul(window_copy_rect.width(), | 570 bitmap->setInfo(SkImageInfo::MakeN32Premul(window_copy_rect.width(), |
| 581 window_copy_rect.height())); | 571 window_copy_rect.height())); |
| 582 current_canvas_->readPixels( | 572 current_canvas_->readPixels( |
| 583 bitmap.get(), window_copy_rect.x(), window_copy_rect.y()); | 573 bitmap.get(), window_copy_rect.x(), window_copy_rect.y()); |
| 584 | 574 |
| 585 request->SendBitmapResult(std::move(bitmap)); | 575 request->SendBitmapResult(std::move(bitmap)); |
| 586 } | 576 } |
| 587 | 577 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 SkBitmap SoftwareRenderer::GetBackdropBitmap( | 641 SkBitmap SoftwareRenderer::GetBackdropBitmap( |
| 652 const gfx::Rect& bounding_rect) const { | 642 const gfx::Rect& bounding_rect) const { |
| 653 SkBitmap bitmap; | 643 SkBitmap bitmap; |
| 654 bitmap.setInfo(SkImageInfo::MakeN32Premul(bounding_rect.width(), | 644 bitmap.setInfo(SkImageInfo::MakeN32Premul(bounding_rect.width(), |
| 655 bounding_rect.height())); | 645 bounding_rect.height())); |
| 656 current_canvas_->readPixels(&bitmap, bounding_rect.x(), bounding_rect.y()); | 646 current_canvas_->readPixels(&bitmap, bounding_rect.x(), bounding_rect.y()); |
| 657 return bitmap; | 647 return bitmap; |
| 658 } | 648 } |
| 659 | 649 |
| 660 gfx::Rect SoftwareRenderer::GetBackdropBoundingBoxForRenderPassQuad( | 650 gfx::Rect SoftwareRenderer::GetBackdropBoundingBoxForRenderPassQuad( |
| 661 const DrawingFrame* frame, | |
| 662 const RenderPassDrawQuad* quad, | 651 const RenderPassDrawQuad* quad, |
| 663 const gfx::Transform& contents_device_transform, | 652 const gfx::Transform& contents_device_transform, |
| 664 const FilterOperations* background_filters, | 653 const FilterOperations* background_filters, |
| 665 gfx::Rect* unclipped_rect) const { | 654 gfx::Rect* unclipped_rect) const { |
| 666 DCHECK(ShouldApplyBackgroundFilters(quad, background_filters)); | 655 DCHECK(ShouldApplyBackgroundFilters(quad, background_filters)); |
| 667 gfx::Rect backdrop_rect = gfx::ToEnclosingRect( | 656 gfx::Rect backdrop_rect = gfx::ToEnclosingRect( |
| 668 MathUtil::MapClippedRect(contents_device_transform, QuadVertexRect())); | 657 MathUtil::MapClippedRect(contents_device_transform, QuadVertexRect())); |
| 669 | 658 |
| 670 SkMatrix matrix; | 659 SkMatrix matrix; |
| 671 matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); | 660 matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); |
| 672 backdrop_rect = background_filters->MapRectReverse(backdrop_rect, matrix); | 661 backdrop_rect = background_filters->MapRectReverse(backdrop_rect, matrix); |
| 673 | 662 |
| 674 *unclipped_rect = backdrop_rect; | 663 *unclipped_rect = backdrop_rect; |
| 675 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( | 664 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( |
| 676 frame, frame->current_render_pass->output_rect)); | 665 current_frame()->current_render_pass->output_rect)); |
| 677 | 666 |
| 678 return backdrop_rect; | 667 return backdrop_rect; |
| 679 } | 668 } |
| 680 | 669 |
| 681 sk_sp<SkShader> SoftwareRenderer::GetBackgroundFilterShader( | 670 sk_sp<SkShader> SoftwareRenderer::GetBackgroundFilterShader( |
| 682 const DrawingFrame* frame, | |
| 683 const RenderPassDrawQuad* quad, | 671 const RenderPassDrawQuad* quad, |
| 684 SkShader::TileMode content_tile_mode) const { | 672 SkShader::TileMode content_tile_mode) const { |
| 685 const FilterOperations* background_filters = | 673 const FilterOperations* background_filters = |
| 686 BackgroundFiltersForPass(quad->render_pass_id); | 674 BackgroundFiltersForPass(quad->render_pass_id); |
| 687 if (!ShouldApplyBackgroundFilters(quad, background_filters)) | 675 if (!ShouldApplyBackgroundFilters(quad, background_filters)) |
| 688 return nullptr; | 676 return nullptr; |
| 689 | 677 |
| 690 gfx::Transform quad_rect_matrix; | 678 gfx::Transform quad_rect_matrix; |
| 691 QuadRectTransform(&quad_rect_matrix, | 679 QuadRectTransform(&quad_rect_matrix, |
| 692 quad->shared_quad_state->quad_to_target_transform, | 680 quad->shared_quad_state->quad_to_target_transform, |
| 693 gfx::RectF(quad->rect)); | 681 gfx::RectF(quad->rect)); |
| 694 gfx::Transform contents_device_transform = | 682 gfx::Transform contents_device_transform = |
| 695 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 683 current_frame()->window_matrix * current_frame()->projection_matrix * |
| 684 quad_rect_matrix; |
| 696 contents_device_transform.FlattenTo2d(); | 685 contents_device_transform.FlattenTo2d(); |
| 697 | 686 |
| 698 gfx::Rect unclipped_rect; | 687 gfx::Rect unclipped_rect; |
| 699 gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad( | 688 gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad( |
| 700 frame, quad, contents_device_transform, background_filters, | 689 quad, contents_device_transform, background_filters, &unclipped_rect); |
| 701 &unclipped_rect); | |
| 702 | 690 |
| 703 // Figure out the transformations to move it back to pixel space. | 691 // Figure out the transformations to move it back to pixel space. |
| 704 gfx::Transform contents_device_transform_inverse; | 692 gfx::Transform contents_device_transform_inverse; |
| 705 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 693 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
| 706 return nullptr; | 694 return nullptr; |
| 707 | 695 |
| 708 SkMatrix filter_backdrop_transform = | 696 SkMatrix filter_backdrop_transform = |
| 709 contents_device_transform_inverse.matrix(); | 697 contents_device_transform_inverse.matrix(); |
| 710 filter_backdrop_transform.preTranslate(backdrop_rect.x(), backdrop_rect.y()); | 698 filter_backdrop_transform.preTranslate(backdrop_rect.x(), backdrop_rect.y()); |
| 711 | 699 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 723 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); | 711 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); |
| 724 | 712 |
| 725 if (!filter_backdrop_image) | 713 if (!filter_backdrop_image) |
| 726 return nullptr; | 714 return nullptr; |
| 727 | 715 |
| 728 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, | 716 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, |
| 729 &filter_backdrop_transform); | 717 &filter_backdrop_transform); |
| 730 } | 718 } |
| 731 | 719 |
| 732 } // namespace cc | 720 } // namespace cc |
| OLD | NEW |