OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "platform/graphics/RecordingImageBufferSurface.h" | 5 #include "platform/graphics/RecordingImageBufferSurface.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
| 8 |
8 #include "platform/Histogram.h" | 9 #include "platform/Histogram.h" |
9 #include "platform/graphics/CanvasMetrics.h" | 10 #include "platform/graphics/CanvasMetrics.h" |
10 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" | 11 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" |
11 #include "platform/graphics/GraphicsContext.h" | 12 #include "platform/graphics/GraphicsContext.h" |
12 #include "platform/graphics/ImageBuffer.h" | 13 #include "platform/graphics/ImageBuffer.h" |
| 14 #include "platform/graphics/UnacceleratedImageBufferSurface.h" |
13 #include "platform/graphics/paint/PaintRecorder.h" | 15 #include "platform/graphics/paint/PaintRecorder.h" |
14 #include "platform/wtf/PassRefPtr.h" | 16 #include "platform/wtf/PassRefPtr.h" |
15 #include "platform/wtf/PtrUtil.h" | 17 #include "platform/wtf/PtrUtil.h" |
16 | 18 |
17 namespace blink { | 19 namespace blink { |
18 | 20 |
19 RecordingImageBufferSurface::RecordingImageBufferSurface( | 21 RecordingImageBufferSurface::RecordingImageBufferSurface( |
20 const IntSize& size, | 22 const IntSize& size, |
21 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> | |
22 fallback_factory, | |
23 OpacityMode opacity_mode, | 23 OpacityMode opacity_mode, |
24 const CanvasColorParams& color_params) | 24 const CanvasColorParams& color_params) |
25 : ImageBufferSurface(size, opacity_mode, color_params), | 25 : ImageBufferSurface(size, opacity_mode, color_params), |
26 image_buffer_(0), | 26 image_buffer_(0), |
27 current_frame_pixel_count_(0), | 27 current_frame_pixel_count_(0), |
28 previous_frame_pixel_count_(0), | 28 previous_frame_pixel_count_(0), |
29 frame_was_cleared_(true), | 29 frame_was_cleared_(true), |
30 did_record_draw_commands_in_current_frame_(false), | 30 did_record_draw_commands_in_current_frame_(false), |
31 current_frame_has_expensive_op_(false), | 31 current_frame_has_expensive_op_(false), |
32 previous_frame_has_expensive_op_(false), | 32 previous_frame_has_expensive_op_(false) { |
33 fallback_factory_(std::move(fallback_factory)) { | |
34 InitializeCurrentFrame(); | 33 InitializeCurrentFrame(); |
35 } | 34 } |
36 | 35 |
37 RecordingImageBufferSurface::~RecordingImageBufferSurface() {} | 36 RecordingImageBufferSurface::~RecordingImageBufferSurface() {} |
38 | 37 |
39 void RecordingImageBufferSurface::InitializeCurrentFrame() { | 38 void RecordingImageBufferSurface::InitializeCurrentFrame() { |
40 current_frame_ = WTF::WrapUnique(new PaintRecorder); | 39 current_frame_ = WTF::WrapUnique(new PaintRecorder); |
41 PaintCanvas* canvas = | 40 PaintCanvas* canvas = |
42 current_frame_->beginRecording(size().Width(), size().Height()); | 41 current_frame_->beginRecording(size().Width(), size().Height()); |
43 // Always save an initial frame, to support resetting the top level matrix | 42 // Always save an initial frame, to support resetting the top level matrix |
(...skipping 17 matching lines...) Expand all Loading... |
61 fallback_surface_->SetImageBuffer(image_buffer); | 60 fallback_surface_->SetImageBuffer(image_buffer); |
62 } | 61 } |
63 } | 62 } |
64 | 63 |
65 bool RecordingImageBufferSurface::WritePixels(const SkImageInfo& orig_info, | 64 bool RecordingImageBufferSurface::WritePixels(const SkImageInfo& orig_info, |
66 const void* pixels, | 65 const void* pixels, |
67 size_t row_bytes, | 66 size_t row_bytes, |
68 int x, | 67 int x, |
69 int y) { | 68 int y) { |
70 if (!fallback_surface_) { | 69 if (!fallback_surface_) { |
71 if (x <= 0 && y <= 0 && x + orig_info.width() >= size().Width() && | 70 IntRect write_rect(x, y, orig_info.width(), orig_info.height()); |
72 y + orig_info.height() >= size().Height()) { | 71 if (write_rect.Contains(IntRect(IntPoint(), size()))) |
73 WillOverwriteCanvas(); | 72 WillOverwriteCanvas(); |
74 } | |
75 FallBackToRasterCanvas(kFallbackReasonWritePixels); | 73 FallBackToRasterCanvas(kFallbackReasonWritePixels); |
76 } | 74 } |
77 return fallback_surface_->WritePixels(orig_info, pixels, row_bytes, x, y); | 75 return fallback_surface_->WritePixels(orig_info, pixels, row_bytes, x, y); |
78 } | 76 } |
79 | 77 |
80 void RecordingImageBufferSurface::FallBackToRasterCanvas( | 78 void RecordingImageBufferSurface::FallBackToRasterCanvas( |
81 FallbackReason reason) { | 79 FallbackReason reason) { |
82 DCHECK(fallback_factory_); | |
83 CHECK(reason != kFallbackReasonUnknown); | 80 CHECK(reason != kFallbackReasonUnknown); |
84 | 81 |
85 if (fallback_surface_) { | 82 if (fallback_surface_) { |
86 DCHECK(!current_frame_); | 83 DCHECK(!current_frame_); |
87 return; | 84 return; |
88 } | 85 } |
89 | 86 |
90 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 87 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
91 EnumerationHistogram, canvas_fallback_histogram, | 88 EnumerationHistogram, canvas_fallback_histogram, |
92 new EnumerationHistogram("Canvas.DisplayListFallbackReason", | 89 new EnumerationHistogram("Canvas.DisplayListFallbackReason", |
93 kFallbackReasonCount)); | 90 kFallbackReasonCount)); |
94 canvas_fallback_histogram.Count(reason); | 91 canvas_fallback_histogram.Count(reason); |
95 | 92 |
96 fallback_surface_ = fallback_factory_->CreateSurface(size(), GetOpacityMode(), | 93 fallback_surface_ = WTF::WrapUnique(new UnacceleratedImageBufferSurface( |
97 color_params()); | 94 size(), GetOpacityMode(), kInitializeImagePixels, color_params())); |
98 fallback_surface_->SetImageBuffer(image_buffer_); | 95 fallback_surface_->SetImageBuffer(image_buffer_); |
99 | 96 |
100 if (previous_frame_) { | 97 if (previous_frame_) { |
101 fallback_surface_->Canvas()->PlaybackPaintRecord(previous_frame_); | 98 fallback_surface_->Canvas()->PlaybackPaintRecord(previous_frame_); |
102 previous_frame_.reset(); | 99 previous_frame_.reset(); |
103 } | 100 } |
104 | 101 |
105 if (current_frame_) { | 102 if (current_frame_) { |
106 sk_sp<PaintRecord> record = current_frame_->finishRecordingAsPicture(); | 103 sk_sp<PaintRecord> record = current_frame_->finishRecordingAsPicture(); |
107 if (record) | 104 if (record) |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 FallBackToRasterCanvas(DisableDeferralReasonToFallbackReason(reason)); | 220 FallBackToRasterCanvas(DisableDeferralReasonToFallbackReason(reason)); |
224 } | 221 } |
225 | 222 |
226 sk_sp<PaintRecord> RecordingImageBufferSurface::GetRecord() { | 223 sk_sp<PaintRecord> RecordingImageBufferSurface::GetRecord() { |
227 if (fallback_surface_) | 224 if (fallback_surface_) |
228 return nullptr; | 225 return nullptr; |
229 | 226 |
230 FallbackReason fallback_reason = kFallbackReasonUnknown; | 227 FallbackReason fallback_reason = kFallbackReasonUnknown; |
231 bool can_use_record = FinalizeFrameInternal(&fallback_reason); | 228 bool can_use_record = FinalizeFrameInternal(&fallback_reason); |
232 | 229 |
233 DCHECK(can_use_record || fallback_factory_); | |
234 | |
235 if (can_use_record) { | 230 if (can_use_record) { |
236 return previous_frame_; | 231 return previous_frame_; |
237 } | 232 } |
238 | 233 |
239 if (!fallback_surface_) | 234 if (!fallback_surface_) |
240 FallBackToRasterCanvas(fallback_reason); | 235 FallBackToRasterCanvas(fallback_reason); |
241 return nullptr; | 236 return nullptr; |
242 } | 237 } |
243 | 238 |
244 void RecordingImageBufferSurface::FinalizeFrame() { | 239 void RecordingImageBufferSurface::FinalizeFrame() { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 } | 308 } |
314 CHECK(current_frame_); | 309 CHECK(current_frame_); |
315 return true; | 310 return true; |
316 } | 311 } |
317 | 312 |
318 if (!frame_was_cleared_) { | 313 if (!frame_was_cleared_) { |
319 *fallback_reason = kFallbackReasonCanvasNotClearedBetweenFrames; | 314 *fallback_reason = kFallbackReasonCanvasNotClearedBetweenFrames; |
320 return false; | 315 return false; |
321 } | 316 } |
322 | 317 |
323 if (fallback_factory_ && | 318 if (current_frame_->getRecordingCanvas()->getSaveCount() - 1 > |
324 current_frame_->getRecordingCanvas()->getSaveCount() - 1 > | 319 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth) { |
325 ExpensiveCanvasHeuristicParameters::kExpensiveRecordingStackDepth) { | |
326 // (getSaveCount() decremented to account for the intial recording canvas | 320 // (getSaveCount() decremented to account for the intial recording canvas |
327 // save frame.) | 321 // save frame.) |
328 *fallback_reason = kFallbackReasonRunawayStateStack; | 322 *fallback_reason = kFallbackReasonRunawayStateStack; |
329 return false; | 323 return false; |
330 } | 324 } |
331 | 325 |
332 previous_frame_ = current_frame_->finishRecordingAsPicture(); | 326 previous_frame_ = current_frame_->finishRecordingAsPicture(); |
333 previous_frame_has_expensive_op_ = current_frame_has_expensive_op_; | 327 previous_frame_has_expensive_op_ = current_frame_has_expensive_op_; |
334 previous_frame_pixel_count_ = current_frame_pixel_count_; | 328 previous_frame_pixel_count_ = current_frame_pixel_count_; |
335 InitializeCurrentFrame(); | 329 InitializeCurrentFrame(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 400 } |
407 | 401 |
408 void RecordingImageBufferSurface::SetIsHidden(bool hidden) { | 402 void RecordingImageBufferSurface::SetIsHidden(bool hidden) { |
409 if (fallback_surface_) | 403 if (fallback_surface_) |
410 fallback_surface_->SetIsHidden(hidden); | 404 fallback_surface_->SetIsHidden(hidden); |
411 else | 405 else |
412 ImageBufferSurface::SetIsHidden(hidden); | 406 ImageBufferSurface::SetIsHidden(hidden); |
413 } | 407 } |
414 | 408 |
415 } // namespace blink | 409 } // namespace blink |
OLD | NEW |