123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "cc/paint/skia_paint_canvas.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/notreached.h"
- #include "base/trace_event/trace_event.h"
- #include "cc/paint/display_item_list.h"
- #include "cc/paint/paint_recorder.h"
- #include "cc/paint/scoped_raster_flags.h"
- #include "cc/paint/skottie_wrapper.h"
- #include "skia/ext/legacy_display_globals.h"
- #include "third_party/skia/include/core/SkAnnotation.h"
- #include "third_party/skia/include/core/SkCanvas.h"
- #include "third_party/skia/include/core/SkImageInfo.h"
- #include "third_party/skia/include/core/SkPoint.h"
- #include "third_party/skia/include/core/SkTextBlob.h"
- #include "third_party/skia/include/docs/SkPDFDocument.h"
- #include "third_party/skia/include/gpu/GrRecordingContext.h"
- namespace cc {
- SkiaPaintCanvas::ContextFlushes::ContextFlushes()
- : enable(false), max_draws_before_flush(-1) {}
- SkiaPaintCanvas::SkiaPaintCanvas(SkCanvas* canvas,
- ImageProvider* image_provider,
- ContextFlushes context_flushes)
- : canvas_(canvas),
- image_provider_(image_provider),
- context_flushes_(context_flushes) {}
- SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap,
- ImageProvider* image_provider)
- : canvas_(new SkCanvas(bitmap,
- skia::LegacyDisplayGlobals::GetSkSurfaceProps())),
- bitmap_(bitmap),
- owned_(canvas_),
- image_provider_(image_provider) {}
- SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap,
- const SkSurfaceProps& props)
- : canvas_(new SkCanvas(bitmap, props)), bitmap_(bitmap), owned_(canvas_) {}
- SkiaPaintCanvas::~SkiaPaintCanvas() = default;
- SkImageInfo SkiaPaintCanvas::imageInfo() const {
- return canvas_->imageInfo();
- }
- void* SkiaPaintCanvas::accessTopLayerPixels(SkImageInfo* info,
- size_t* rowBytes,
- SkIPoint* origin) {
- if (bitmap_.isNull() || bitmap_.isImmutable())
- return nullptr;
- return canvas_->accessTopLayerPixels(info, rowBytes, origin);
- }
- void SkiaPaintCanvas::flush() {
- canvas_->flush();
- }
- bool SkiaPaintCanvas::NeedsFlush() const {
- // Since flush() is always capable of flushing immediately with
- // SkiaPaintCanvas, there is never any need for deferred flushing.
- return false;
- }
- int SkiaPaintCanvas::save() {
- return canvas_->save();
- }
- int SkiaPaintCanvas::saveLayer(const SkRect* bounds, const PaintFlags* flags) {
- if (!flags)
- return canvas_->saveLayer(bounds, nullptr);
- SkPaint paint = flags->ToSkPaint();
- return canvas_->saveLayer(bounds, &paint);
- }
- int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
- return canvas_->saveLayerAlpha(bounds, alpha);
- }
- void SkiaPaintCanvas::restore() {
- canvas_->restore();
- }
- int SkiaPaintCanvas::getSaveCount() const {
- return canvas_->getSaveCount();
- }
- void SkiaPaintCanvas::restoreToCount(int save_count) {
- canvas_->restoreToCount(save_count);
- }
- void SkiaPaintCanvas::translate(SkScalar dx, SkScalar dy) {
- canvas_->translate(dx, dy);
- }
- void SkiaPaintCanvas::scale(SkScalar sx, SkScalar sy) {
- canvas_->scale(sx, sy);
- }
- void SkiaPaintCanvas::rotate(SkScalar degrees) {
- canvas_->rotate(degrees);
- }
- void SkiaPaintCanvas::setMatrix(const SkM44& matrix) {
- canvas_->setMatrix(matrix);
- }
- void SkiaPaintCanvas::concat(const SkM44& matrix) {
- canvas_->concat(matrix);
- }
- void SkiaPaintCanvas::concat(const SkMatrix& matrix) {
- canvas_->concat(matrix);
- }
- void SkiaPaintCanvas::setMatrix(const SkMatrix& matrix) {
- canvas_->setMatrix(matrix);
- }
- void SkiaPaintCanvas::clipRect(const SkRect& rect,
- SkClipOp op,
- bool do_anti_alias) {
- canvas_->clipRect(rect, op, do_anti_alias);
- }
- void SkiaPaintCanvas::clipRRect(const SkRRect& rrect,
- SkClipOp op,
- bool do_anti_alias) {
- canvas_->clipRRect(rrect, op, do_anti_alias);
- }
- void SkiaPaintCanvas::clipPath(const SkPath& path,
- SkClipOp op,
- bool do_anti_alias,
- UsePaintCache) {
- canvas_->clipPath(path, op, do_anti_alias);
- }
- SkRect SkiaPaintCanvas::getLocalClipBounds() const {
- return canvas_->getLocalClipBounds();
- }
- bool SkiaPaintCanvas::getLocalClipBounds(SkRect* bounds) const {
- return canvas_->getLocalClipBounds(bounds);
- }
- SkIRect SkiaPaintCanvas::getDeviceClipBounds() const {
- return canvas_->getDeviceClipBounds();
- }
- bool SkiaPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
- return canvas_->getDeviceClipBounds(bounds);
- }
- void SkiaPaintCanvas::drawColor(SkColor4f color, SkBlendMode mode) {
- canvas_->drawColor(color, mode);
- }
- void SkiaPaintCanvas::clear(SkColor4f color) {
- canvas_->clear(color);
- }
- void SkiaPaintCanvas::drawLine(SkScalar x0,
- SkScalar y0,
- SkScalar x1,
- SkScalar y1,
- const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_, [x0, y0, x1, y1](SkCanvas* c, const SkPaint& p) {
- c->drawLine(x0, y0, x1, y1, p);
- });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_,
- [&rect](SkCanvas* c, const SkPaint& p) { c->drawRect(rect, p); });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawIRect(const SkIRect& rect, const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_,
- [&rect](SkCanvas* c, const SkPaint& p) { c->drawIRect(rect, p); });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_,
- [&oval](SkCanvas* c, const SkPaint& p) { c->drawOval(oval, p); });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawRRect(const SkRRect& rrect, const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_,
- [&rrect](SkCanvas* c, const SkPaint& p) { c->drawRRect(rrect, p); });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawDRRect(const SkRRect& outer,
- const SkRRect& inner,
- const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_, [&outer, &inner](SkCanvas* c, const SkPaint& p) {
- c->drawDRRect(outer, inner, p);
- });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawRoundRect(const SkRect& rect,
- SkScalar rx,
- SkScalar ry,
- const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_, [&rect, rx, ry](SkCanvas* c, const SkPaint& p) {
- c->drawRoundRect(rect, rx, ry, p);
- });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawPath(const SkPath& path,
- const PaintFlags& flags,
- UsePaintCache) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(
- canvas_,
- [&path](SkCanvas* c, const SkPaint& p) { c->drawPath(path, p); });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawImage(const PaintImage& image,
- SkScalar left,
- SkScalar top,
- const SkSamplingOptions& sampling,
- const PaintFlags* flags) {
- DCHECK(!image.IsPaintWorklet());
- absl::optional<ScopedRasterFlags> scoped_flags;
- if (flags) {
- scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(),
- GetMaxTextureSize(), 1.0f);
- if (!scoped_flags->flags())
- return;
- }
- const PaintFlags* raster_flags = scoped_flags ? scoped_flags->flags() : flags;
- PlaybackParams params(image_provider_, canvas_->getLocalToDevice());
- DrawImageOp draw_image_op(image, left, top, sampling, nullptr);
- DrawImageOp::RasterWithFlags(&draw_image_op, raster_flags, canvas_, params);
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawImageRect(const PaintImage& image,
- const SkRect& src,
- const SkRect& dst,
- const SkSamplingOptions& sampling,
- const PaintFlags* flags,
- SkCanvas::SrcRectConstraint constraint) {
- absl::optional<ScopedRasterFlags> scoped_flags;
- if (flags) {
- scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(),
- GetMaxTextureSize(), 1.0f);
- if (!scoped_flags->flags())
- return;
- }
- const PaintFlags* raster_flags = scoped_flags ? scoped_flags->flags() : flags;
- PlaybackParams params(image_provider_, canvas_->getLocalToDevice());
- DrawImageRectOp draw_image_rect_op(image, src, dst, sampling, flags,
- constraint);
- DrawImageRectOp::RasterWithFlags(&draw_image_rect_op, raster_flags, canvas_,
- params);
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawSkottie(scoped_refptr<SkottieWrapper> skottie,
- const SkRect& dst,
- float t,
- SkottieFrameDataMap images,
- const SkottieColorMap& color_map,
- SkottieTextPropertyValueMap text_map) {
- if (!images.empty()) {
- // This is not implemented solely because there's no use case yet. To
- // implement, we could retrieve the underlying SkImage from each
- // PaintImage in |images| here and call SkottieWrapper::SetImageForAsset().
- NOTIMPLEMENTED()
- << "Rendering skottie frames with image assets directly to a "
- "SkiaPaintCanvas is currently not supported.";
- }
- skottie->Draw(canvas_, t, dst, SkottieWrapper::FrameDataCallback(), color_map,
- std::move(text_map));
- }
- void SkiaPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
- SkScalar x,
- SkScalar y,
- const PaintFlags& flags) {
- ScopedRasterFlags raster_flags(&flags, image_provider_,
- canvas_->getTotalMatrix(), GetMaxTextureSize(),
- 1.0f);
- if (!raster_flags.flags())
- return;
- raster_flags.flags()->DrawToSk(canvas_,
- [&blob, x, y](SkCanvas* c, const SkPaint& p) {
- c->drawTextBlob(blob, x, y, p);
- });
- FlushAfterDrawIfNeeded();
- }
- void SkiaPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
- SkScalar x,
- SkScalar y,
- NodeId node_id,
- const PaintFlags& flags) {
- if (node_id)
- SkPDF::SetNodeId(canvas_, node_id);
- drawTextBlob(blob, x, y, flags);
- if (node_id)
- SkPDF::SetNodeId(canvas_, 0);
- }
- void SkiaPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) {
- drawPicture(record, PlaybackParams::CustomDataRasterCallback());
- }
- bool SkiaPaintCanvas::isClipEmpty() const {
- return canvas_->isClipEmpty();
- }
- SkMatrix SkiaPaintCanvas::getTotalMatrix() const {
- return canvas_->getTotalMatrix();
- }
- SkM44 SkiaPaintCanvas::getLocalToDevice() const {
- return canvas_->getLocalToDevice();
- }
- void SkiaPaintCanvas::Annotate(AnnotationType type,
- const SkRect& rect,
- sk_sp<SkData> data) {
- switch (type) {
- case AnnotationType::URL:
- SkAnnotateRectWithURL(canvas_, rect, data.get());
- break;
- case AnnotationType::LINK_TO_DESTINATION:
- SkAnnotateLinkToDestination(canvas_, rect, data.get());
- break;
- case AnnotationType::NAMED_DESTINATION: {
- SkPoint point = SkPoint::Make(rect.x(), rect.y());
- SkAnnotateNamedDestination(canvas_, point, data.get());
- break;
- }
- }
- }
- void SkiaPaintCanvas::setNodeId(int node_id) {
- SkPDF::SetNodeId(canvas_, node_id);
- }
- void SkiaPaintCanvas::drawPicture(
- sk_sp<const PaintRecord> record,
- PlaybackParams::CustomDataRasterCallback custom_raster_callback) {
- auto did_draw_op_cb =
- context_flushes_.enable
- ? base::BindRepeating(&SkiaPaintCanvas::FlushAfterDrawIfNeeded,
- base::Unretained(this))
- : PlaybackParams::DidDrawOpCallback();
- PlaybackParams params(image_provider_, canvas_->getLocalToDevice(),
- custom_raster_callback, did_draw_op_cb);
- record->Playback(canvas_, params);
- }
- void SkiaPaintCanvas::FlushAfterDrawIfNeeded() {
- if (!context_flushes_.enable)
- return;
- if (++num_of_ops_ > context_flushes_.max_draws_before_flush) {
- num_of_ops_ = 0;
- TRACE_EVENT0("cc",
- "SkiaPaintCanvas::FlushAfterDrawIfNeeded::FlushGrContext");
- canvas_->flush();
- }
- }
- int SkiaPaintCanvas::GetMaxTextureSize() const {
- auto* context = canvas_->recordingContext();
- return context ? context->maxTextureSize() : 0;
- }
- } // namespace cc
|