Commit 7a2c8f70 authored by Brian Salomon's avatar Brian Salomon Committed by Commit Bot

Use updated DDL recorder promise image APIs

New versions don't have Done procs, allow null for release procs, and
the YUVA variation internally figures out the texture channels from
higher level inputs (formats + planar configuration).

Bug: skia:10632
Change-Id: Ifb49bcb2fce4edc88b0c4425f9031be37113fd81
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537878Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Cr-Commit-Position: refs/heads/master@{#827791}
parent 562e8dca
......@@ -16,6 +16,7 @@
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/overlay_processor_interface.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkYUVAInfo.h"
#if defined(OS_WIN)
#include "components/viz/service/display/dc_layer_overlay.h"
......@@ -89,16 +90,13 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
ExternalUseClient::ImageContext* image_context) = 0;
// Make a promise SkImage from the given |contexts| and |image_color_space|.
// For YUV format, at least three resource contexts should be provided.
// contexts[0] contains pixels from y panel, contexts[1] contains pixels
// from u panel, contexts[2] contains pixels from v panel. For NV12 format,
// at least two resource contexts should be provided. contexts[0] contains
// pixels from y panel, contexts[1] contains pixels from u and v panels. If
// has_alpha is true, the last item in contexts contains alpha panel.
// The number of contexts provided should match the number of planes indicated
// by plane_config.
virtual sk_sp<SkImage> MakePromiseSkImageFromYUV(
const std::vector<ExternalUseClient::ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
bool has_alpha) = 0;
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) = 0;
// Called if SwapBuffers() will be skipped.
virtual void SwapBuffersSkipped() = 0;
......
......@@ -608,10 +608,20 @@ class SkiaRenderer::ScopedYUVSkImageBuilder {
IsTextureResource(skia_renderer->resource_provider_,
quad->a_plane_resource_id()));
const bool is_i420 =
quad->u_plane_resource_id() != quad->v_plane_resource_id();
const bool has_alpha = quad->a_plane_resource_id() != kInvalidResourceId;
const size_t number_of_textures = (is_i420 ? 3 : 2) + (has_alpha ? 1 : 0);
// The image is always either NV12 or I420, possibly with a separate alpha
// plane.
SkYUVAInfo::PlaneConfig plane_config;
if (quad->a_plane_resource_id() == kInvalidResourceId) {
plane_config = quad->u_plane_resource_id() == quad->v_plane_resource_id()
? SkYUVAInfo::PlaneConfig::kY_UV
: SkYUVAInfo::PlaneConfig::kY_U_V;
} else {
plane_config = quad->u_plane_resource_id() == quad->v_plane_resource_id()
? SkYUVAInfo::PlaneConfig::kY_UV_A
: SkYUVAInfo::PlaneConfig::kY_U_V_A;
}
const SkYUVAInfo::Subsampling subsampling = SkYUVAInfo::Subsampling::k420;
const int number_of_textures = SkYUVAInfo::NumPlanes(plane_config);
std::vector<ExternalUseClient::ImageContext*> contexts;
contexts.reserve(number_of_textures);
// Skia API ignores the color space information on the individual planes.
......@@ -622,13 +632,14 @@ class SkiaRenderer::ScopedYUVSkImageBuilder {
auto* u_context = skia_renderer->lock_set_for_external_use_->LockResource(
quad->u_plane_resource_id(), /*is_video_plane=*/true);
contexts.push_back(std::move(u_context));
if (is_i420) {
if (plane_config == SkYUVAInfo::PlaneConfig::kY_U_V ||
plane_config == SkYUVAInfo::PlaneConfig::kY_U_V_A) {
auto* v_context = skia_renderer->lock_set_for_external_use_->LockResource(
quad->v_plane_resource_id(), /*is_video_plane=*/true);
contexts.push_back(std::move(v_context));
}
if (has_alpha) {
if (SkYUVAInfo::HasAlpha(plane_config)) {
auto* a_context = skia_renderer->lock_set_for_external_use_->LockResource(
quad->a_plane_resource_id(), /*is_video_plane=*/true);
contexts.push_back(std::move(a_context));
......@@ -636,7 +647,7 @@ class SkiaRenderer::ScopedYUVSkImageBuilder {
// Note: YUV to RGB and color conversion is handled by a color filter.
sk_image_ = skia_renderer->skia_output_surface_->MakePromiseSkImageFromYUV(
std::move(contexts), dst_color_space, has_alpha);
std::move(contexts), dst_color_space, plane_config, subsampling);
LOG_IF(ERROR, !sk_image_) << "Failed to create the promise sk yuva image.";
}
......
......@@ -33,6 +33,7 @@
#include "gpu/vulkan/buildflags.h"
#include "skia/buildflags.h"
#include "skia/ext/legacy_display_globals.h"
#include "third_party/skia/include/gpu/GrYUVABackendTextures.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_gl_api_implementation.h"
......@@ -56,8 +57,6 @@ sk_sp<SkPromiseImageTexture> Fulfill(void* texture_context) {
return sk_ref_sp(image_context->promise_image_texture());
}
void DoNothing(void* texture_context) {}
gpu::ContextUrl& GetActiveUrl() {
static base::NoDestructor<gpu::ContextUrl> active_url(
GURL("chrome://gpu/SkiaRenderer"));
......@@ -333,8 +332,7 @@ void SkiaOutputSurfaceImpl::MakePromiseSkImage(ImageContext* image_context) {
image_context->size().height(), GrMipMapped::kNo,
image_context->origin(), color_type, image_context->alpha_type(),
image_context->color_space(), Fulfill /* fulfillProc */,
DoNothing /* releaseProc */, DoNothing /* doneProc */,
image_context /* context */),
nullptr /* releaseProc */, image_context /* context */),
backend_format);
if (image_context->mailbox_holder().sync_token.HasData()) {
......@@ -346,17 +344,19 @@ void SkiaOutputSurfaceImpl::MakePromiseSkImage(ImageContext* image_context) {
sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromYUV(
const std::vector<ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
bool has_alpha) {
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_paint_);
DCHECK((has_alpha && (contexts.size() == 3 || contexts.size() == 4)) ||
(!has_alpha && (contexts.size() == 2 || contexts.size() == 3)));
DCHECK(static_cast<size_t>(SkYUVAInfo::NumPlanes(plane_config)) ==
contexts.size());
SkYUVAIndex indices[4];
PrepareYUVATextureIndices(contexts, has_alpha, indices);
auto* y_context = static_cast<ImageContextImpl*>(contexts[0]);
// Note: YUV to RGB conversion is handled by a color filter in SkiaRenderer.
SkYUVAInfo yuva_info({y_context->size().width(), y_context->size().height()},
plane_config, subsampling, kIdentity_SkYUVColorSpace);
GrBackendFormat formats[4] = {};
SkISize yuva_sizes[4] = {};
SkDeferredDisplayListRecorder::PromiseImageTextureContext
texture_contexts[4] = {};
for (size_t i = 0; i < contexts.size(); ++i) {
......@@ -365,7 +365,6 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromYUV(
formats[i] = GetGrBackendFormatForTexture(
context->resource_format(), context->mailbox_holder().texture_target,
/*ycbcr_info=*/base::nullopt);
yuva_sizes[i].set(context->size().width(), context->size().height());
// NOTE: We don't have promises for individual planes, but still need format
// for fallback
......@@ -379,11 +378,11 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromYUV(
texture_contexts[i] = context;
}
// Note: YUV to RGB conversion is handled by a color filter in SkiaRenderer.
GrYUVABackendTextureInfo yuva_backend_info(
yuva_info, formats, GrMipmapped::kNo, kTopLeft_GrSurfaceOrigin);
auto image = current_paint_->recorder()->makeYUVAPromiseTexture(
kIdentity_SkYUVColorSpace, formats, yuva_sizes, indices,
yuva_sizes[0].width(), yuva_sizes[0].height(), kTopLeft_GrSurfaceOrigin,
image_color_space, Fulfill, DoNothing, DoNothing, texture_contexts);
yuva_backend_info, std::move(image_color_space), Fulfill,
/*textureReleaseProc=*/nullptr, texture_contexts);
DCHECK(image);
return image;
}
......@@ -623,8 +622,8 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromRenderPass(
backend_format, image_context->size().width(),
image_context->size().height(), image_context->mipmap(),
image_context->origin(), color_type, image_context->alpha_type(),
image_context->color_space(), Fulfill, DoNothing, DoNothing,
image_context.get()),
image_context->color_space(), Fulfill,
/*releaseTextureProc=*/nullptr, image_context.get()),
backend_format);
if (!image_context->has_image()) {
return nullptr;
......@@ -1108,39 +1107,6 @@ gpu::SyncToken SkiaOutputSurfaceImpl::Flush() {
return sync_token;
}
void SkiaOutputSurfaceImpl::PrepareYUVATextureIndices(
const std::vector<ImageContext*>& contexts,
bool has_alpha,
SkYUVAIndex indices[4]) {
DCHECK((has_alpha && (contexts.size() == 3 || contexts.size() == 4)) ||
(!has_alpha && (contexts.size() == 2 || contexts.size() == 3)));
bool uv_interleaved = has_alpha ? contexts.size() == 3 : contexts.size() == 2;
indices[SkYUVAIndex::kY_Index].fIndex = 0;
indices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR;
if (uv_interleaved) {
indices[SkYUVAIndex::kU_Index].fIndex = 1;
indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
indices[SkYUVAIndex::kV_Index].fIndex = 1;
indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kG;
indices[SkYUVAIndex::kA_Index].fIndex = has_alpha ? 2 : -1;
indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
} else {
indices[SkYUVAIndex::kU_Index].fIndex = 1;
indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
indices[SkYUVAIndex::kV_Index].fIndex = 2;
indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kR;
indices[SkYUVAIndex::kA_Index].fIndex = has_alpha ? 3 : -1;
indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
}
}
void SkiaOutputSurfaceImpl::ContextLost() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DLOG(ERROR) << "SkiaOutputSurfaceImpl::ContextLost()";
......
......@@ -25,7 +25,6 @@
#include "third_party/skia/include/core/SkDeferredDisplayListRecorder.h"
#include "third_party/skia/include/core/SkOverdrawCanvas.h"
#include "third_party/skia/include/core/SkSurfaceCharacterization.h"
#include "third_party/skia/include/core/SkYUVAIndex.h"
namespace viz {
......@@ -95,7 +94,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
sk_sp<SkImage> MakePromiseSkImageFromYUV(
const std::vector<ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
bool has_alpha) override;
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) override;
void SwapBuffersSkipped() override;
void ScheduleOutputSurfaceAsOverlay(
OverlayProcessorInterface::OutputSurfaceOverlayPlane output_surface_plane)
......@@ -184,9 +184,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
ResourceFormat resource_format,
uint32_t gl_texture_target,
const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info);
void PrepareYUVATextureIndices(const std::vector<ImageContext*>& contexts,
bool has_alpha,
SkYUVAIndex indices[4]);
void ContextLost();
void RecreateRootRecorder();
......
......@@ -162,7 +162,8 @@ void FakeSkiaOutputSurface::MakePromiseSkImage(ImageContext* image_context) {
sk_sp<SkImage> FakeSkiaOutputSurface::MakePromiseSkImageFromYUV(
const std::vector<ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
bool has_alpha) {
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
NOTIMPLEMENTED();
return nullptr;
......
......@@ -72,7 +72,8 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
sk_sp<SkImage> MakePromiseSkImageFromYUV(
const std::vector<ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
bool has_alpha) override;
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) override;
void SwapBuffersSkipped() override {}
SkCanvas* BeginPaintRenderPass(const AggregatedRenderPassId& id,
const gfx::Size& surface_size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment