blob: 3001841e4651ce661bf7696d083ceb4d3c0f4731 [file] [log] [blame]
// Copyright 2020 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 "third_party/blink/renderer/platform/graphics/mailbox_texture_backing.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/mailbox_ref.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
namespace blink {
MailboxTextureBacking::MailboxTextureBacking(
sk_sp<SkImage> sk_image,
scoped_refptr<MailboxRef> mailbox_ref,
const SkImageInfo& info,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper)
: sk_image_(std::move(sk_image)),
mailbox_ref_(std::move(mailbox_ref)),
sk_image_info_(info),
context_provider_wrapper_(std::move(context_provider_wrapper)) {}
MailboxTextureBacking::MailboxTextureBacking(
const gpu::Mailbox& mailbox,
scoped_refptr<MailboxRef> mailbox_ref,
const SkImageInfo& info,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper)
: mailbox_(mailbox),
mailbox_ref_(std::move(mailbox_ref)),
sk_image_info_(info),
context_provider_wrapper_(std::move(context_provider_wrapper)) {}
MailboxTextureBacking::~MailboxTextureBacking() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (context_provider_wrapper_) {
gpu::raster::RasterInterface* ri =
context_provider_wrapper_->ContextProvider()->RasterInterface();
// Update the sync token for MailboxRef.
ri->WaitSyncTokenCHROMIUM(mailbox_ref_->sync_token().GetConstData());
gpu::SyncToken sync_token;
ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
mailbox_ref_->set_sync_token(sync_token);
}
}
const SkImageInfo& MailboxTextureBacking::GetSkImageInfo() {
return sk_image_info_;
}
gpu::Mailbox MailboxTextureBacking::GetMailbox() const {
return mailbox_;
}
sk_sp<SkImage> MailboxTextureBacking::GetAcceleratedSkImage() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return sk_image_;
}
sk_sp<SkImage> MailboxTextureBacking::GetSkImageViaReadback() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!mailbox_.IsZero()) {
if (!context_provider_wrapper_)
return nullptr;
// TODO(jochin): Consider doing some caching and using discardable memory.
sk_sp<SkData> image_pixels =
TryAllocateSkData(sk_image_info_.computeMinByteSize());
if (!image_pixels)
return nullptr;
uint8_t* writable_pixels =
static_cast<uint8_t*>(image_pixels->writable_data());
gpu::raster::RasterInterface* ri =
context_provider_wrapper_->ContextProvider()->RasterInterface();
ri->ReadbackImagePixels(mailbox_, sk_image_info_,
sk_image_info_.minRowBytes(), 0, 0,
writable_pixels);
return SkImage::MakeRasterData(sk_image_info_, std::move(image_pixels),
sk_image_info_.minRowBytes());
} else if (sk_image_) {
return sk_image_->makeNonTextureImage();
}
return nullptr;
}
bool MailboxTextureBacking::readPixels(const SkImageInfo& dst_info,
void* dst_pixels,
size_t dst_row_bytes,
int src_x,
int src_y) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!mailbox_.IsZero()) {
if (!context_provider_wrapper_)
return false;
gpu::raster::RasterInterface* ri =
context_provider_wrapper_->ContextProvider()->RasterInterface();
ri->ReadbackImagePixels(mailbox_, dst_info, dst_info.minRowBytes(), src_x,
src_y, dst_pixels);
return true;
} else if (sk_image_) {
return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x,
src_y);
}
return false;
}
void MailboxTextureBacking::FlushPendingSkiaOps() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!context_provider_wrapper_ || !sk_image_)
return;
sk_image_->flushAndSubmit(
context_provider_wrapper_->ContextProvider()->GetGrContext());
}
} // namespace blink