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 |