Chromium Code Reviews| 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/base/render_surface_filters.h" | 10 #include "cc/base/render_surface_filters.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) { | 44 bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) { |
| 45 return IsScalarNearlyInteger(matrix[SkMatrix::kMTransX]) && | 45 return IsScalarNearlyInteger(matrix[SkMatrix::kMTransX]) && |
| 46 IsScalarNearlyInteger(matrix[SkMatrix::kMTransY]) && | 46 IsScalarNearlyInteger(matrix[SkMatrix::kMTransY]) && |
| 47 SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) && | 47 SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) && |
| 48 SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) && | 48 SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) && |
| 49 SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) && | 49 SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) && |
| 50 SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) && | 50 SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) && |
| 51 SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f); | 51 SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f); |
| 52 } | 52 } |
| 53 | 53 |
| 54 class ScopedSaveCanvas { | |
|
enne (OOO)
2017/05/09 01:02:11
I think this is SkAutoCanvasRestore. You can even
ericrk
2017/05/09 15:53:18
Yay! I couldn't find this earlier.
| |
| 55 public: | |
| 56 explicit ScopedSaveCanvas(SkCanvas* canvas) | |
| 57 : canvas_(canvas), save_count_(canvas->save()) {} | |
| 58 ~ScopedSaveCanvas() { | |
| 59 canvas_->restore(); | |
| 60 DCHECK_EQ(save_count_, canvas_->getSaveCount()); | |
| 61 } | |
| 62 | |
| 63 private: | |
| 64 SkCanvas* canvas_; | |
| 65 int save_count_; | |
| 66 | |
| 67 DISALLOW_COPY_AND_ASSIGN(ScopedSaveCanvas); | |
| 68 }; | |
| 69 | |
| 54 } // anonymous namespace | 70 } // anonymous namespace |
| 55 | 71 |
| 56 SoftwareRenderer::SoftwareRenderer(const RendererSettings* settings, | 72 SoftwareRenderer::SoftwareRenderer(const RendererSettings* settings, |
| 57 OutputSurface* output_surface, | 73 OutputSurface* output_surface, |
| 58 ResourceProvider* resource_provider) | 74 ResourceProvider* resource_provider) |
| 59 : DirectRenderer(settings, output_surface, resource_provider), | 75 : DirectRenderer(settings, output_surface, resource_provider), |
| 60 output_device_(output_surface->software_device()) { | 76 output_device_(output_surface->software_device()) { |
| 61 } | 77 } |
| 62 | 78 |
| 63 SoftwareRenderer::~SoftwareRenderer() {} | 79 SoftwareRenderer::~SoftwareRenderer() {} |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 92 output_frame.latency_info = std::move(latency_info); | 108 output_frame.latency_info = std::move(latency_info); |
| 93 output_surface_->SwapBuffers(std::move(output_frame)); | 109 output_surface_->SwapBuffers(std::move(output_frame)); |
| 94 } | 110 } |
| 95 | 111 |
| 96 bool SoftwareRenderer::FlippedFramebuffer() const { | 112 bool SoftwareRenderer::FlippedFramebuffer() const { |
| 97 return false; | 113 return false; |
| 98 } | 114 } |
| 99 | 115 |
| 100 void SoftwareRenderer::EnsureScissorTestEnabled() { | 116 void SoftwareRenderer::EnsureScissorTestEnabled() { |
| 101 is_scissor_enabled_ = true; | 117 is_scissor_enabled_ = true; |
| 102 SetClipRect(scissor_rect_); | |
| 103 } | 118 } |
| 104 | 119 |
| 105 void SoftwareRenderer::EnsureScissorTestDisabled() { | 120 void SoftwareRenderer::EnsureScissorTestDisabled() { |
| 106 // There is no explicit notion of enabling/disabling scissoring in software | |
| 107 // rendering, but the underlying effect we want is to clear any existing | |
| 108 // clipRect on the current SkCanvas. This is done by setting clipRect to | |
| 109 // the viewport's dimensions. | |
| 110 if (!current_canvas_) | |
| 111 return; | |
| 112 is_scissor_enabled_ = false; | 121 is_scissor_enabled_ = false; |
| 113 SkISize size = current_canvas_->getBaseLayerSize(); | |
| 114 SetClipRect(gfx::Rect(size.width(), size.height())); | |
| 115 } | 122 } |
| 116 | 123 |
| 117 void SoftwareRenderer::BindFramebufferToOutputSurface() { | 124 void SoftwareRenderer::BindFramebufferToOutputSurface() { |
| 118 DCHECK(!output_surface_->HasExternalStencilTest()); | 125 DCHECK(!output_surface_->HasExternalStencilTest()); |
| 119 current_framebuffer_lock_ = nullptr; | 126 current_framebuffer_lock_ = nullptr; |
| 120 current_framebuffer_canvas_.reset(); | 127 current_framebuffer_canvas_.reset(); |
| 121 current_canvas_ = root_canvas_; | 128 current_canvas_ = root_canvas_; |
| 122 } | 129 } |
| 123 | 130 |
| 124 bool SoftwareRenderer::BindFramebufferToTexture( | 131 bool SoftwareRenderer::BindFramebufferToTexture( |
| 125 const ScopedResource* texture) { | 132 const ScopedResource* texture) { |
| 126 DCHECK(texture->id()); | 133 DCHECK(texture->id()); |
| 127 | 134 |
| 128 // Explicitly release lock, otherwise we can crash when try to lock | 135 // Explicitly release lock, otherwise we can crash when try to lock |
| 129 // same texture again. | 136 // same texture again. |
| 130 current_framebuffer_lock_ = nullptr; | 137 current_framebuffer_lock_ = nullptr; |
| 131 current_framebuffer_lock_ = | 138 current_framebuffer_lock_ = |
| 132 base::MakeUnique<ResourceProvider::ScopedWriteLockSoftware>( | 139 base::MakeUnique<ResourceProvider::ScopedWriteLockSoftware>( |
| 133 resource_provider_, texture->id()); | 140 resource_provider_, texture->id()); |
| 134 current_framebuffer_canvas_ = | 141 current_framebuffer_canvas_ = |
| 135 base::MakeUnique<SkCanvas>(current_framebuffer_lock_->sk_bitmap()); | 142 base::MakeUnique<SkCanvas>(current_framebuffer_lock_->sk_bitmap()); |
| 136 current_canvas_ = current_framebuffer_canvas_.get(); | 143 current_canvas_ = current_framebuffer_canvas_.get(); |
| 137 return true; | 144 return true; |
| 138 } | 145 } |
| 139 | 146 |
| 140 void SoftwareRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { | 147 void SoftwareRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { |
| 141 is_scissor_enabled_ = true; | 148 is_scissor_enabled_ = true; |
| 142 scissor_rect_ = scissor_rect; | 149 scissor_rect_ = scissor_rect; |
| 143 SetClipRect(scissor_rect); | |
| 144 } | 150 } |
| 145 | 151 |
| 146 void SoftwareRenderer::SetClipRect(const gfx::Rect& rect) { | 152 void SoftwareRenderer::SetClipRect(const gfx::Rect& rect) { |
| 147 if (!current_canvas_) | 153 if (!current_canvas_) |
| 148 return; | 154 return; |
| 149 // Skia applies the current matrix to clip rects so we reset it temporary. | 155 // Skia applies the current matrix to clip rects so we reset it temporary. |
| 150 SkMatrix current_matrix = current_canvas_->getTotalMatrix(); | 156 SkMatrix current_matrix = current_canvas_->getTotalMatrix(); |
| 151 current_canvas_->resetMatrix(); | 157 current_canvas_->resetMatrix(); |
|
f(malita)
2017/05/09 13:24:03
// SetClipRect is assumed to be applied temporaril
ericrk
2017/05/09 15:53:18
Good suggestion. done.
| |
| 152 // TODO(fmalita) stop using kReplace (see crbug.com/673851) | 158 current_canvas_->clipRect(gfx::RectToSkRect(rect), SkClipOp::kIntersect); |
|
f(malita)
2017/05/09 13:24:03
nit: you can omit the clipOp - it defaults to inte
ericrk
2017/05/09 15:53:18
Done.
| |
| 153 current_canvas_->clipRect(gfx::RectToSkRect(rect), | |
| 154 SkClipOp::kReplace_deprecated); | |
| 155 current_canvas_->setMatrix(current_matrix); | 159 current_canvas_->setMatrix(current_matrix); |
| 156 } | 160 } |
| 157 | 161 |
| 158 void SoftwareRenderer::ClearCanvas(SkColor color) { | 162 void SoftwareRenderer::ClearCanvas(SkColor color) { |
| 159 if (!current_canvas_) | 163 if (!current_canvas_) |
| 160 return; | 164 return; |
| 161 current_canvas_->clear(color); | 165 current_canvas_->clear(color); |
| 162 } | 166 } |
| 163 | 167 |
| 164 void SoftwareRenderer::ClearFramebuffer() { | 168 void SoftwareRenderer::ClearFramebuffer() { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 } | 205 } |
| 202 | 206 |
| 203 LOG(FATAL) << "Invalid resource type."; | 207 LOG(FATAL) << "Invalid resource type."; |
| 204 return false; | 208 return false; |
| 205 } | 209 } |
| 206 | 210 |
| 207 void SoftwareRenderer::DoDrawQuad(const DrawQuad* quad, | 211 void SoftwareRenderer::DoDrawQuad(const DrawQuad* quad, |
| 208 const gfx::QuadF* draw_region) { | 212 const gfx::QuadF* draw_region) { |
| 209 if (!current_canvas_) | 213 if (!current_canvas_) |
| 210 return; | 214 return; |
| 211 if (draw_region) { | 215 |
| 212 current_canvas_->save(); | 216 TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad"); |
| 217 base::Optional<ScopedSaveCanvas> scoped_save_canvas_; | |
|
reed1
2017/05/09 11:50:46
Can this section just be:
SkAutoCanvasRestore acr
ericrk
2017/05/09 15:53:18
Refactored - I think we still only want to save/cl
| |
| 218 if (draw_region || is_scissor_enabled_) { | |
| 219 scoped_save_canvas_.emplace(current_canvas_); | |
| 220 } | |
| 221 if (is_scissor_enabled_) { | |
| 222 SetClipRect(scissor_rect_); | |
| 213 } | 223 } |
| 214 | 224 |
| 215 TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad"); | |
| 216 gfx::Transform quad_rect_matrix; | 225 gfx::Transform quad_rect_matrix; |
| 217 QuadRectTransform(&quad_rect_matrix, | 226 QuadRectTransform(&quad_rect_matrix, |
| 218 quad->shared_quad_state->quad_to_target_transform, | 227 quad->shared_quad_state->quad_to_target_transform, |
| 219 gfx::RectF(quad->rect)); | 228 gfx::RectF(quad->rect)); |
| 220 gfx::Transform contents_device_transform = | 229 gfx::Transform contents_device_transform = |
| 221 current_frame()->window_matrix * current_frame()->projection_matrix * | 230 current_frame()->window_matrix * current_frame()->projection_matrix * |
| 222 quad_rect_matrix; | 231 quad_rect_matrix; |
| 223 contents_device_transform.FlattenTo2d(); | 232 contents_device_transform.FlattenTo2d(); |
| 224 SkMatrix sk_device_matrix; | 233 SkMatrix sk_device_matrix; |
| 225 gfx::TransformToFlattenedSkMatrix(contents_device_transform, | 234 gfx::TransformToFlattenedSkMatrix(contents_device_transform, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 break; | 300 break; |
| 292 case DrawQuad::INVALID: | 301 case DrawQuad::INVALID: |
| 293 case DrawQuad::YUV_VIDEO_CONTENT: | 302 case DrawQuad::YUV_VIDEO_CONTENT: |
| 294 case DrawQuad::STREAM_VIDEO_CONTENT: | 303 case DrawQuad::STREAM_VIDEO_CONTENT: |
| 295 DrawUnsupportedQuad(quad); | 304 DrawUnsupportedQuad(quad); |
| 296 NOTREACHED(); | 305 NOTREACHED(); |
| 297 break; | 306 break; |
| 298 } | 307 } |
| 299 | 308 |
| 300 current_canvas_->resetMatrix(); | 309 current_canvas_->resetMatrix(); |
| 301 if (draw_region) { | |
| 302 current_canvas_->restore(); | |
| 303 } | |
| 304 } | 310 } |
| 305 | 311 |
| 306 void SoftwareRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { | 312 void SoftwareRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { |
| 307 // We need to apply the matrix manually to have pixel-sized stroke width. | 313 // We need to apply the matrix manually to have pixel-sized stroke width. |
| 308 SkPoint vertices[4]; | 314 SkPoint vertices[4]; |
| 309 gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); | 315 gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices); |
| 310 SkPoint transformed_vertices[4]; | 316 SkPoint transformed_vertices[4]; |
| 311 current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, | 317 current_canvas_->getTotalMatrix().mapPoints(transformed_vertices, |
| 312 vertices, | 318 vertices, |
| 313 4); | 319 4); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 727 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); | 733 ApplyImageFilter(filter.get(), quad, backdrop_bitmap, nullptr); |
| 728 | 734 |
| 729 if (!filter_backdrop_image) | 735 if (!filter_backdrop_image) |
| 730 return nullptr; | 736 return nullptr; |
| 731 | 737 |
| 732 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, | 738 return filter_backdrop_image->makeShader(content_tile_mode, content_tile_mode, |
| 733 &filter_backdrop_transform); | 739 &filter_backdrop_transform); |
| 734 } | 740 } |
| 735 | 741 |
| 736 } // namespace cc | 742 } // namespace cc |
| OLD | NEW |