Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: cc/output/software_renderer.cc

Issue 2867913002: Avoid using SkClipOp::kReplace_deprecated in software renderer (Closed)
Patch Set: add extra robustness to ScopedSaveCanvas Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | cc/output/software_renderer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | cc/output/software_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698