123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- // Copyright 2019 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 "components/paint_preview/renderer/paint_preview_recorder_utils.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/trace_event/common/trace_event_common.h"
- #include "base/trace_event/trace_event.h"
- #include "cc/paint/paint_image.h"
- #include "cc/paint/paint_image_builder.h"
- #include "components/paint_preview/common/file_stream.h"
- #include "components/paint_preview/common/paint_preview_tracker.h"
- #include "mojo/public/cpp/base/shared_memory_utils.h"
- #include "third_party/skia/include/core/SkData.h"
- #include "third_party/skia/include/core/SkRefCnt.h"
- namespace paint_preview {
- namespace {
- // Converts a texture backed paint image in the PaintOpBuffer to one that is not
- // texture backed.
- cc::PaintImage MakeUnaccelerated(cc::PaintImage& paint_image) {
- DCHECK(paint_image.IsTextureBacked());
- auto sk_image = paint_image.GetSwSkImage();
- if (sk_image->isLazyGenerated()) {
- // Texture backed images should always be returned as SkImage_Raster type
- // (bitmap). This is just a catchall in the event a lazy image is somehow
- // returned in which case we should just raster it.
- SkBitmap bitmap;
- bitmap.allocPixels(sk_image->imageInfo(),
- sk_image->imageInfo().minRowBytes());
- if (!sk_image->readPixels(bitmap.pixmap(), 0, 0)) {
- return paint_image;
- }
- // Make immutable to skip an extra copy.
- bitmap.setImmutable();
- sk_image = SkImage::MakeFromBitmap(bitmap);
- }
- return cc::PaintImageBuilder::WithDefault()
- .set_id(cc::PaintImage::GetNextId())
- .set_image(sk_image, cc::PaintImage::GetNextContentId())
- .TakePaintImage();
- }
- } // namespace
- void PreProcessPaintOpBuffer(const cc::PaintOpBuffer* buffer,
- PaintPreviewTracker* tracker) {
- for (cc::PaintOpBuffer::Iterator it(buffer); it; ++it) {
- switch (it->GetType()) {
- case cc::PaintOpType::DrawTextBlob: {
- auto* text_blob_op = static_cast<cc::DrawTextBlobOp*>(*it);
- tracker->AddGlyphs(text_blob_op->blob.get());
- break;
- }
- case cc::PaintOpType::DrawRecord: {
- // Recurse into nested records if they contain text blobs (equivalent to
- // nested SkPictures).
- auto* record_op = static_cast<cc::DrawRecordOp*>(*it);
- PreProcessPaintOpBuffer(record_op->record.get(), tracker);
- break;
- }
- case cc::PaintOpType::Annotate: {
- auto* annotate_op = static_cast<cc::AnnotateOp*>(*it);
- tracker->AnnotateLink(GURL(std::string(reinterpret_cast<const char*>(
- annotate_op->data->data()),
- annotate_op->data->size())),
- annotate_op->rect);
- // Delete the data. We no longer need it.
- annotate_op->data.reset();
- break;
- }
- case cc::PaintOpType::CustomData: {
- auto* custom_op = static_cast<cc::CustomDataOp*>(*it);
- tracker->TransformClipForFrame(custom_op->id);
- break;
- }
- case cc::PaintOpType::Save: {
- tracker->Save();
- break;
- }
- case cc::PaintOpType::SaveLayer: {
- tracker->Save();
- break;
- }
- case cc::PaintOpType::SaveLayerAlpha: {
- tracker->Save();
- break;
- }
- case cc::PaintOpType::Restore: {
- tracker->Restore();
- break;
- }
- case cc::PaintOpType::SetMatrix: {
- auto* matrix_op = static_cast<cc::SetMatrixOp*>(*it);
- tracker->SetMatrix(matrix_op->matrix.asM33());
- break;
- }
- case cc::PaintOpType::Concat: {
- auto* concat_op = static_cast<cc::ConcatOp*>(*it);
- tracker->Concat(concat_op->matrix.asM33());
- break;
- }
- case cc::PaintOpType::Scale: {
- auto* scale_op = static_cast<cc::ScaleOp*>(*it);
- tracker->Scale(scale_op->sx, scale_op->sy);
- break;
- }
- case cc::PaintOpType::Rotate: {
- auto* rotate_op = static_cast<cc::RotateOp*>(*it);
- tracker->Rotate(rotate_op->degrees);
- break;
- }
- case cc::PaintOpType::Translate: {
- auto* translate_op = static_cast<cc::TranslateOp*>(*it);
- tracker->Translate(translate_op->dx, translate_op->dy);
- break;
- }
- case cc::PaintOpType::DrawImage: {
- auto* image_op = static_cast<cc::DrawImageOp*>(*it);
- if (image_op->image.IsTextureBacked()) {
- image_op->image = MakeUnaccelerated(image_op->image);
- }
- break;
- }
- case cc::PaintOpType::DrawImageRect: {
- auto* image_op = static_cast<cc::DrawImageRectOp*>(*it);
- if (image_op->image.IsTextureBacked()) {
- image_op->image = MakeUnaccelerated(image_op->image);
- }
- break;
- }
- default:
- continue;
- }
- }
- }
- sk_sp<const SkPicture> PaintRecordToSkPicture(
- sk_sp<const cc::PaintRecord> recording,
- PaintPreviewTracker* tracker,
- const gfx::Rect& bounds) {
- // base::Unretained is safe as |tracker| outlives the usage of
- // |custom_callback|.
- cc::PlaybackParams::CustomDataRasterCallback custom_callback =
- base::BindRepeating(&PaintPreviewTracker::CustomDataToSkPictureCallback,
- base::Unretained(tracker));
- auto skp =
- ToSkPicture(recording, SkRect::MakeWH(bounds.width(), bounds.height()),
- nullptr, custom_callback);
- if (!skp || skp->cullRect().width() == 0 || skp->cullRect().height() == 0)
- return nullptr;
- return skp;
- }
- void BuildResponse(PaintPreviewTracker* tracker,
- mojom::PaintPreviewCaptureResponse* response) {
- // Ensure these always exist.
- DCHECK(tracker);
- DCHECK(response);
- response->embedding_token = tracker->EmbeddingToken();
- tracker->MoveLinks(&response->links);
- PictureSerializationContext* picture_context =
- tracker->GetPictureSerializationContext();
- if (!picture_context)
- return;
- for (const auto& id_pair : picture_context->content_id_to_embedding_token) {
- response->content_id_to_embedding_token.insert(id_pair);
- }
- }
- } // namespace paint_preview
|