summaryrefslogtreecommitdiffstats
path: root/chromium/cc/paint/record_paint_canvas.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2023-02-13 16:03:23 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2023-05-26 11:26:35 +0000
commit813d9ae984a99e739b99cf694a9d5b24d0a6b7a7 (patch)
tree60c14d40d77a3c702c8a72887662d97c0b8f3e99 /chromium/cc/paint/record_paint_canvas.cc
parenteb596ba9fe579987eb93f6b4021ca156885b48c2 (diff)
BASELINE: Update Chromium to 110.0.5481.111
Change-Id: I2b5f5ed66fee2a6f8da61c9b17fd1b25bb5b3a4e Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/464348 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/paint/record_paint_canvas.cc')
-rw-r--r--chromium/cc/paint/record_paint_canvas.cc292
1 files changed, 190 insertions, 102 deletions
diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc
index 6f378a60a88..d08866332b1 100644
--- a/chromium/cc/paint/record_paint_canvas.cc
+++ b/chromium/cc/paint/record_paint_canvas.cc
@@ -6,8 +6,8 @@
#include <utility>
-#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_image_builder.h"
+#include "cc/paint/paint_op.h"
#include "cc/paint/paint_record.h"
#include "cc/paint/paint_recorder.h"
#include "cc/paint/skottie_frame_data.h"
@@ -18,20 +18,19 @@
namespace cc {
-RecordPaintCanvas::RecordPaintCanvas(DisplayItemList* list,
- const SkRect& bounds)
- : list_(list), recording_bounds_(bounds) {
- DCHECK(list_);
-}
-
+RecordPaintCanvas::RecordPaintCanvas() = default;
RecordPaintCanvas::~RecordPaintCanvas() = default;
-SkImageInfo RecordPaintCanvas::imageInfo() const {
- return GetCanvas()->imageInfo();
+sk_sp<PaintRecord> RecordPaintCanvas::ReleaseAsRecord() {
+ // Some users expect that their saves are automatically closed for them.
+ // Maybe we could remove this assumption and just have callers do it.
+ restoreToCount(1);
+ needs_flush_ = false;
+ return buffer_.MoveRetainingBufferIfPossible();
}
template <typename T, typename... Args>
-size_t RecordPaintCanvas::push(Args&&... args) {
+void RecordPaintCanvas::push(Args&&... args) {
#if DCHECK_IS_ON()
// The following check fails if client code does not check and handle
// NeedsFlush() before issuing draw calls.
@@ -43,7 +42,7 @@ size_t RecordPaintCanvas::push(Args&&... args) {
(std::is_same<T, RestoreOp>::value) ||
(std::is_same<T, SetNodeIdOp>::value));
#endif
- return list_->push<T>(std::forward<Args>(args)...);
+ buffer_.push<T>(std::forward<Args>(args)...);
}
void* RecordPaintCanvas::accessTopLayerPixels(SkImageInfo* info,
@@ -58,9 +57,9 @@ void RecordPaintCanvas::flush() {
// pipeline. So instead we make note of the flush request so that it can be
// handled by code that owns the recording.
//
- // Note: The value of needs_flush_ never gets reset. That is because
- // flushing a recording implies closing this RecordPaintCanvas and starting a
- // new one.
+ // Note: The value of needs_flush_ never gets reset until the end of
+ // recording. That is because flushing a recording implies ReleaseAsRecord()
+ // and starting a new recording.
needs_flush_ = true;
}
@@ -70,52 +69,44 @@ bool RecordPaintCanvas::NeedsFlush() const {
int RecordPaintCanvas::save() {
push<SaveOp>();
- return GetCanvas()->save();
+ return save_count_++;
}
int RecordPaintCanvas::saveLayer(const SkRect* bounds,
const PaintFlags* flags) {
- if (flags) {
- if (flags->IsSimpleOpacity()) {
- // TODO(enne): maybe more callers should know this and call
- // saveLayerAlpha instead of needing to check here.
- uint8_t alpha = SkColorGetA(flags->getColor());
- return saveLayerAlpha(bounds, alpha);
- }
-
- // TODO(enne): it appears that image filters affect matrices and color
- // matrices affect transparent flags on SkCanvas layers, but it's not clear
- // whether those are actually needed and we could just skip ToSkPaint here.
- push<SaveLayerOp>(bounds, flags);
- SkPaint paint = flags->ToSkPaint();
- return GetCanvas()->saveLayer(bounds, &paint);
+ if (flags && flags->IsSimpleOpacity()) {
+ // TODO(enne): maybe more callers should know this and call
+ // saveLayerAlpha instead of needing to check here.
+ uint8_t alpha = SkColorGetA(flags->getColor());
+ return saveLayerAlpha(bounds, alpha);
}
+ return saveLayerInternal(bounds, flags);
+}
+
+int RecordPaintCanvas::saveLayerInternal(const SkRect* bounds,
+ const PaintFlags* flags) {
push<SaveLayerOp>(bounds, flags);
- return GetCanvas()->saveLayer(bounds, nullptr);
+ return save_count_++;
}
int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
push<SaveLayerAlphaOp>(bounds, static_cast<float>(alpha / 255.0f));
- return GetCanvas()->saveLayerAlpha(bounds, alpha);
+ return save_count_++;
}
void RecordPaintCanvas::restore() {
push<RestoreOp>();
- GetCanvas()->restore();
+ --save_count_;
+ DCHECK_GE(save_count_, 1);
}
int RecordPaintCanvas::getSaveCount() const {
- return GetCanvas()->getSaveCount();
+ return save_count_;
}
void RecordPaintCanvas::restoreToCount(int save_count) {
- if (!canvas_) {
- DCHECK_EQ(save_count, 1);
- return;
- }
-
DCHECK_GE(save_count, 1);
- int diff = GetCanvas()->getSaveCount() - save_count;
+ int diff = getSaveCount() - save_count;
DCHECK_GE(diff, 0);
for (int i = 0; i < diff; ++i)
restore();
@@ -123,68 +114,59 @@ void RecordPaintCanvas::restoreToCount(int save_count) {
void RecordPaintCanvas::translate(SkScalar dx, SkScalar dy) {
push<TranslateOp>(dx, dy);
- GetCanvas()->translate(dx, dy);
}
void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) {
push<ScaleOp>(sx, sy);
- GetCanvas()->scale(sx, sy);
}
void RecordPaintCanvas::rotate(SkScalar degrees) {
push<RotateOp>(degrees);
- GetCanvas()->rotate(degrees);
}
void RecordPaintCanvas::concat(const SkMatrix& matrix) {
- SkM44 m = SkM44(matrix);
- push<ConcatOp>(m);
- GetCanvas()->concat(m);
+ concat(SkM44(matrix));
}
void RecordPaintCanvas::concat(const SkM44& matrix) {
push<ConcatOp>(matrix);
- GetCanvas()->concat(matrix);
}
void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) {
- SkM44 m = SkM44(matrix);
- push<SetMatrixOp>(m);
- GetCanvas()->setMatrix(m);
+ setMatrix(SkM44(matrix));
}
void RecordPaintCanvas::setMatrix(const SkM44& matrix) {
push<SetMatrixOp>(matrix);
- GetCanvas()->setMatrix(matrix);
}
void RecordPaintCanvas::clipRect(const SkRect& rect,
SkClipOp op,
bool antialias) {
push<ClipRectOp>(rect, op, antialias);
- GetCanvas()->clipRect(rect, op, antialias);
}
void RecordPaintCanvas::clipRRect(const SkRRect& rrect,
SkClipOp op,
bool antialias) {
- // TODO(enne): does this happen? Should the caller know this?
if (rrect.isRect()) {
clipRect(rrect.getBounds(), op, antialias);
return;
}
+ clipRRectInternal(rrect, op, antialias);
+}
+
+void RecordPaintCanvas::clipRRectInternal(const SkRRect& rrect,
+ SkClipOp op,
+ bool antialias) {
push<ClipRRectOp>(rrect, op, antialias);
- GetCanvas()->clipRRect(rrect, op, antialias);
}
void RecordPaintCanvas::clipPath(const SkPath& path,
SkClipOp op,
bool antialias,
UsePaintCache use_paint_cache) {
- if (!path.isInverseFillType() &&
- GetCanvas()->getTotalMatrix().rectStaysRect()) {
- // TODO(enne): do these cases happen? should the caller know that this isn't
- // a path?
+ if (!path.isInverseFillType()) {
SkRect rect;
if (path.isRect(&rect)) {
clipRect(rect, op, antialias);
@@ -201,30 +183,54 @@ void RecordPaintCanvas::clipPath(const SkPath& path,
return;
}
}
+ clipPathInternal(path, op, antialias, use_paint_cache);
+}
+void RecordPaintCanvas::clipPathInternal(const SkPath& path,
+ SkClipOp op,
+ bool antialias,
+ UsePaintCache use_paint_cache) {
push<ClipPathOp>(path, op, antialias, use_paint_cache);
- GetCanvas()->clipPath(path, op, antialias);
- return;
+}
+
+SkImageInfo RecordPaintCanvas::imageInfo() const {
+ NOTREACHED();
+ return SkImageInfo();
}
SkRect RecordPaintCanvas::getLocalClipBounds() const {
- DCHECK(InitializedWithRecordingBounds());
- return GetCanvas()->getLocalClipBounds();
+ NOTREACHED();
+ return SkRect();
}
bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const {
- DCHECK(InitializedWithRecordingBounds());
- return GetCanvas()->getLocalClipBounds(bounds);
+ NOTREACHED();
+ return false;
}
SkIRect RecordPaintCanvas::getDeviceClipBounds() const {
- DCHECK(InitializedWithRecordingBounds());
- return GetCanvas()->getDeviceClipBounds();
+ NOTREACHED();
+ return SkIRect();
}
bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
- DCHECK(InitializedWithRecordingBounds());
- return GetCanvas()->getDeviceClipBounds(bounds);
+ NOTREACHED();
+ return false;
+}
+
+bool RecordPaintCanvas::isClipEmpty() const {
+ NOTREACHED();
+ return true;
+}
+
+SkMatrix RecordPaintCanvas::getTotalMatrix() const {
+ NOTREACHED();
+ return SkMatrix();
+}
+
+SkM44 RecordPaintCanvas::getLocalToDevice() const {
+ NOTREACHED();
+ return SkM44();
}
void RecordPaintCanvas::drawColor(SkColor4f color, SkBlendMode mode) {
@@ -341,19 +347,6 @@ void RecordPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) {
push<DrawRecordOp>(record);
}
-bool RecordPaintCanvas::isClipEmpty() const {
- DCHECK(InitializedWithRecordingBounds());
- return GetCanvas()->isClipEmpty();
-}
-
-SkMatrix RecordPaintCanvas::getTotalMatrix() const {
- return GetCanvas()->getTotalMatrix();
-}
-
-SkM44 RecordPaintCanvas::getLocalToDevice() const {
- return GetCanvas()->getLocalToDevice();
-}
-
void RecordPaintCanvas::Annotate(AnnotationType type,
const SkRect& rect,
sk_sp<SkData> data) {
@@ -368,34 +361,129 @@ void RecordPaintCanvas::setNodeId(int node_id) {
push<SetNodeIdOp>(node_id);
}
-const SkNoDrawCanvas* RecordPaintCanvas::GetCanvas() const {
- return const_cast<RecordPaintCanvas*>(this)->GetCanvas();
+InspectableRecordPaintCanvas::InspectableRecordPaintCanvas(
+ const gfx::Size& size)
+ : canvas_(size.width(), size.height()) {}
+
+InspectableRecordPaintCanvas::~InspectableRecordPaintCanvas() = default;
+
+int InspectableRecordPaintCanvas::save() {
+ return CheckSaveCount(RecordPaintCanvas::save(), canvas_.save());
+}
+
+int InspectableRecordPaintCanvas::saveLayerInternal(const SkRect* bounds,
+ const PaintFlags* flags) {
+ int canvas_prev_save_count;
+ // TODO(enne): it appears that image filters affect matrices and color
+ // matrices affect transparent flags on SkCanvas layers, but it's not clear
+ // whether those are actually needed and we could just skip ToSkPaint here.
+ if (flags) {
+ SkPaint paint = flags->ToSkPaint();
+ canvas_prev_save_count = canvas_.saveLayer(bounds, &paint);
+ } else {
+ canvas_prev_save_count = canvas_.saveLayer(bounds, nullptr);
+ }
+ return CheckSaveCount(RecordPaintCanvas::saveLayerInternal(bounds, flags),
+ canvas_prev_save_count);
+}
+
+int InspectableRecordPaintCanvas::saveLayerAlpha(const SkRect* bounds,
+ uint8_t alpha) {
+ return CheckSaveCount(RecordPaintCanvas::saveLayerAlpha(bounds, alpha),
+ canvas_.saveLayerAlpha(bounds, alpha));
+}
+
+void InspectableRecordPaintCanvas::restore() {
+ RecordPaintCanvas::restore();
+ canvas_.restore();
+ DCHECK_EQ(getSaveCount(), canvas_.getSaveCount());
+}
+
+int InspectableRecordPaintCanvas::CheckSaveCount(int super_prev_save_count,
+ int canvas_prev_save_count) {
+ DCHECK_EQ(super_prev_save_count, canvas_prev_save_count);
+ DCHECK_EQ(getSaveCount(), canvas_.getSaveCount());
+ return super_prev_save_count;
+}
+
+void InspectableRecordPaintCanvas::translate(SkScalar dx, SkScalar dy) {
+ RecordPaintCanvas::translate(dx, dy);
+ canvas_.translate(dx, dy);
+}
+
+void InspectableRecordPaintCanvas::scale(SkScalar sx, SkScalar sy) {
+ RecordPaintCanvas::scale(sx, sy);
+ canvas_.scale(sx, sy);
+}
+
+void InspectableRecordPaintCanvas::rotate(SkScalar degrees) {
+ RecordPaintCanvas::rotate(degrees);
+ canvas_.rotate(degrees);
+}
+
+void InspectableRecordPaintCanvas::concat(const SkM44& matrix) {
+ RecordPaintCanvas::concat(matrix);
+ canvas_.concat(matrix);
+}
+
+void InspectableRecordPaintCanvas::setMatrix(const SkM44& matrix) {
+ RecordPaintCanvas::setMatrix(matrix);
+ canvas_.setMatrix(matrix);
+}
+
+void InspectableRecordPaintCanvas::clipRect(const SkRect& rect,
+ SkClipOp op,
+ bool antialias) {
+ RecordPaintCanvas::clipRect(rect, op, antialias);
+ canvas_.clipRect(rect, op, antialias);
}
-SkNoDrawCanvas* RecordPaintCanvas::GetCanvas() {
- if (canvas_)
- return &*canvas_;
+void InspectableRecordPaintCanvas::clipRRectInternal(const SkRRect& rrect,
+ SkClipOp op,
+ bool antialias) {
+ RecordPaintCanvas::clipRRectInternal(rrect, op, antialias);
+ canvas_.clipRRect(rrect, op, antialias);
+}
+
+void InspectableRecordPaintCanvas::clipPathInternal(
+ const SkPath& path,
+ SkClipOp op,
+ bool antialias,
+ UsePaintCache use_paint_cache) {
+ RecordPaintCanvas::clipPathInternal(path, op, antialias, use_paint_cache);
+ canvas_.clipPath(path, op, antialias);
+}
+
+SkImageInfo InspectableRecordPaintCanvas::imageInfo() const {
+ return canvas_.imageInfo();
+}
- // Size the canvas to be large enough to contain the |recording_bounds|, which
- // may not be positioned at the origin.
- SkIRect enclosing_rect = recording_bounds_.roundOut();
- canvas_.emplace(enclosing_rect.right(), enclosing_rect.bottom());
+SkRect InspectableRecordPaintCanvas::getLocalClipBounds() const {
+ return canvas_.getLocalClipBounds();
+}
+
+bool InspectableRecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const {
+ return canvas_.getLocalClipBounds(bounds);
+}
+
+SkIRect InspectableRecordPaintCanvas::getDeviceClipBounds() const {
+ return canvas_.getDeviceClipBounds();
+}
+
+bool InspectableRecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
+ return canvas_.getDeviceClipBounds(bounds);
+}
+
+bool InspectableRecordPaintCanvas::isClipEmpty() const {
+ return canvas_.isClipEmpty();
+}
- // This is part of the "recording canvases have a size, but why" dance.
- // By creating a canvas of size (right x bottom) and then clipping it,
- // It makes getDeviceClipBounds return the original cull rect, which code
- // in GraphicsContextCanvas on Mac expects. (Just creating an SkNoDrawCanvas
- // with the recording_bounds_ makes a canvas of size (width x height) instead
- // which is incorrect. SkRecorder cheats with private resetForNextCanvas.
- canvas_->clipRect(recording_bounds_, SkClipOp::kIntersect, false);
- return &*canvas_;
+SkMatrix InspectableRecordPaintCanvas::getTotalMatrix() const {
+ return canvas_.getTotalMatrix();
}
-bool RecordPaintCanvas::InitializedWithRecordingBounds() const {
- // If the RecordPaintCanvas is initialized with an empty bounds then
- // the various clip related functions are not valid and should not
- // be called.
- return !recording_bounds_.isEmpty();
+SkM44 InspectableRecordPaintCanvas::getLocalToDevice() const {
+ return canvas_.getLocalToDevice();
}
} // namespace cc