Revert "Revert "New variant of SkImage::MakeFromYUVATextures.""
This reverts commit be8004d2fb
.
Bug: skia:10632
Change-Id: I52dd36ae167623563c7554c40092442a3822ee3c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327760
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
bcd1fc030a
commit
c1a249d1dc
@ -9,6 +9,11 @@ Milestone 88
|
||||
|
||||
* <insert new release notes here>
|
||||
|
||||
* New variant of SkImage::MakeFromYUVATextures. Takes a new type GrYUVATextures
|
||||
which wraps an SkYUVAInfo and compatible set of GrBackendTextures. The provides
|
||||
a more complete and structured specification of the planar configuration. Previous
|
||||
version is deprecated.
|
||||
|
||||
* Add field to GrContextOptions to disable mipmap support even if the backend
|
||||
supports it.
|
||||
|
||||
|
@ -19,6 +19,7 @@ skia_gpu_sources = [
|
||||
"$_include/gpu/GrDriverBugWorkarounds.h",
|
||||
"$_include/gpu/GrRecordingContext.h",
|
||||
"$_include/gpu/GrTypes.h",
|
||||
"$_include/gpu/GrYUVABackendTextures.h",
|
||||
|
||||
# Private includes
|
||||
"$_include/private/GrContext.h",
|
||||
@ -269,6 +270,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrWindowRectsState.h",
|
||||
"$_src/gpu/GrXferProcessor.cpp",
|
||||
"$_src/gpu/GrXferProcessor.h",
|
||||
"$_src/gpu/GrYUVABackendTextures.cpp",
|
||||
|
||||
# Ops
|
||||
"$_src/gpu/effects/GrBezierEffect.cpp",
|
||||
|
@ -38,6 +38,7 @@ class GrContext;
|
||||
class GrDirectContext;
|
||||
class GrRecordingContext;
|
||||
class GrContextThreadSafeProxy;
|
||||
class GrYUVABackendTextures;
|
||||
|
||||
struct SkYUVAIndex;
|
||||
|
||||
@ -408,7 +409,30 @@ public:
|
||||
SkAlphaType alphaType = kPremul_SkAlphaType,
|
||||
sk_sp<SkColorSpace> colorSpace = nullptr);
|
||||
|
||||
/** Creates an SkImage by storing the specified YUVA planes into an image, to be rendered
|
||||
/** Creates an SkImage from YUV[A] planar textures. This requires that the textures stay valid
|
||||
for the lifetime of the image. The ReleaseContext can be used to know when it is safe to
|
||||
either delete or overwrite the textures. If ReleaseProc is provided it is also called before
|
||||
return on failure.
|
||||
|
||||
@param context GPU context
|
||||
@param yuvaTextures A set of textures containing YUVA data and a description of the
|
||||
data and transformation to RGBA.
|
||||
@param imageColorSpace range of colors of the resulting image after conversion to RGB;
|
||||
may be nullptr
|
||||
@param textureReleaseProc called when the backend textures can be released
|
||||
@param releaseContext state passed to textureReleaseProc
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromYUVATextures(GrRecordingContext* context,
|
||||
const GrYUVABackendTextures& yuvaTextures,
|
||||
sk_sp<SkColorSpace> imageColorSpace = nullptr,
|
||||
TextureReleaseProc textureReleaseProc = nullptr,
|
||||
ReleaseContext releaseContext = nullptr);
|
||||
|
||||
/**
|
||||
Deprecated. Use version that takes GrYUVABackendTextures.
|
||||
|
||||
Creates an SkImage by storing the specified YUVA planes into an image, to be rendered
|
||||
via multitexturing.
|
||||
|
||||
When all the provided backend textures can be released 'textureReleaseProc' will be called
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
* this expands.
|
||||
*/
|
||||
enum class PlanarConfig {
|
||||
kUnknown,
|
||||
|
||||
kY_U_V_444, ///< Plane 0: Y, Plane 1: U, Plane 2: V
|
||||
kY_U_V_422, ///< Plane 0: Y, Plane 1: U, Plane 2: V
|
||||
kY_U_V_420, ///< Plane 0: Y, Plane 1: U, Plane 2: V
|
||||
@ -177,10 +179,12 @@ public:
|
||||
bool operator==(const SkYUVAInfo& that) const;
|
||||
bool operator!=(const SkYUVAInfo& that) const { return !(*this == that); }
|
||||
|
||||
bool isValid() const { return fPlanarConfig != PlanarConfig::kUnknown; }
|
||||
|
||||
private:
|
||||
SkISize fDimensions = {0, 0};
|
||||
|
||||
PlanarConfig fPlanarConfig = PlanarConfig::kY_U_V_444;
|
||||
PlanarConfig fPlanarConfig = PlanarConfig::kUnknown;
|
||||
|
||||
SkYUVColorSpace fYUVColorSpace = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
|
||||
|
||||
@ -196,6 +200,8 @@ private:
|
||||
|
||||
constexpr int SkYUVAInfo::NumPlanes(PlanarConfig planarConfig) {
|
||||
switch (planarConfig) {
|
||||
case PlanarConfig::kUnknown: return 0;
|
||||
|
||||
case PlanarConfig::kY_U_V_444: return 3;
|
||||
case PlanarConfig::kY_U_V_422: return 3;
|
||||
case PlanarConfig::kY_U_V_420: return 3;
|
||||
@ -223,6 +229,9 @@ constexpr int SkYUVAInfo::NumPlanes(PlanarConfig planarConfig) {
|
||||
|
||||
constexpr int SkYUVAInfo::NumChannelsInPlane(PlanarConfig config, int i) {
|
||||
switch (config) {
|
||||
case PlanarConfig::kUnknown:
|
||||
return 0;
|
||||
|
||||
case SkYUVAInfo::PlanarConfig::kY_U_V_444:
|
||||
case SkYUVAInfo::PlanarConfig::kY_U_V_422:
|
||||
case SkYUVAInfo::PlanarConfig::kY_U_V_420:
|
||||
|
60
include/gpu/GrYUVABackendTextures.h
Normal file
60
include/gpu/GrYUVABackendTextures.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrYUVABackendTextures_DEFINED
|
||||
#define GrYUVABackendTextures_DEFINED
|
||||
|
||||
#include "include/core/SkYUVAInfo.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
struct SkYUVASizeInfo;
|
||||
struct SkYUVAIndex;
|
||||
|
||||
/**
|
||||
* A set of GrBackendTextures that hold the planar data for a SkYUVAInfo.
|
||||
*/
|
||||
class SK_API GrYUVABackendTextures {
|
||||
public:
|
||||
GrYUVABackendTextures() = default;
|
||||
GrYUVABackendTextures(const GrYUVABackendTextures&) = delete;
|
||||
GrYUVABackendTextures(GrYUVABackendTextures&&) = default;
|
||||
|
||||
GrYUVABackendTextures& operator=(const GrYUVABackendTextures&) = delete;
|
||||
GrYUVABackendTextures& operator=(GrYUVABackendTextures&&) = default;
|
||||
|
||||
GrYUVABackendTextures(const SkYUVAInfo&,
|
||||
const GrBackendTexture[SkYUVAInfo::kMaxPlanes],
|
||||
GrSurfaceOrigin textureOrigin);
|
||||
|
||||
const std::array<GrBackendTexture, SkYUVAInfo::kMaxPlanes>& textures() const {
|
||||
return fTextures;
|
||||
}
|
||||
|
||||
GrBackendTexture texture(int i) const {
|
||||
SkASSERT(i >= 0 && i < SkYUVAInfo::kMaxPlanes);
|
||||
return fTextures[static_cast<size_t>(i)];
|
||||
}
|
||||
|
||||
const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }
|
||||
|
||||
int numPlanes() const { return fYUVAInfo.numPlanes(); }
|
||||
|
||||
GrSurfaceOrigin textureOrigin() const { return fTextureOrigin; }
|
||||
|
||||
bool isValid() const { return fYUVAInfo.isValid(); }
|
||||
|
||||
bool toYUVAIndices(SkYUVAIndex[SkYUVAIndex::kIndexCount]) const;
|
||||
|
||||
private:
|
||||
SkYUVAInfo fYUVAInfo;
|
||||
std::array<GrBackendTexture, SkYUVAInfo::kMaxPlanes> fTextures;
|
||||
GrSurfaceOrigin fTextureOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
};
|
||||
|
||||
#endif
|
@ -11,7 +11,7 @@
|
||||
int SkYUVAInfo::PlaneDimensions(SkISize imageDimensions,
|
||||
PlanarConfig planarConfig,
|
||||
SkEncodedOrigin origin,
|
||||
SkISize* planeDimensions) {
|
||||
SkISize planeDimensions[SkYUVAInfo::kMaxPlanes]) {
|
||||
int w = imageDimensions.width();
|
||||
int h = imageDimensions.height();
|
||||
if (origin >= kLeftTop_SkEncodedOrigin) {
|
||||
@ -21,6 +21,12 @@ int SkYUVAInfo::PlaneDimensions(SkISize imageDimensions,
|
||||
auto down2 = [](int x) { return (x + 1)/2; };
|
||||
auto down4 = [](int x) { return (x + 3)/4; };
|
||||
switch (planarConfig) {
|
||||
case PlanarConfig::kUnknown:
|
||||
planeDimensions[0] =
|
||||
planeDimensions[1] =
|
||||
planeDimensions[2] =
|
||||
planeDimensions[3] = {0, 0};
|
||||
return 0;
|
||||
case PlanarConfig::kY_U_V_444:
|
||||
planeDimensions[0] = planeDimensions[1] = planeDimensions[2] = {w, h};
|
||||
planeDimensions[3] = {0, 0};
|
||||
@ -125,6 +131,9 @@ bool SkYUVAInfo::GetYUVAIndices(PlanarConfig config,
|
||||
struct Location {int plane, chanIdx;};
|
||||
const Location* locations = nullptr;
|
||||
switch (config) {
|
||||
case PlanarConfig::kUnknown:
|
||||
return false;
|
||||
|
||||
case PlanarConfig::kY_U_V_444:
|
||||
case PlanarConfig::kY_U_V_422:
|
||||
case PlanarConfig::kY_U_V_420:
|
||||
@ -210,6 +219,8 @@ bool SkYUVAInfo::GetYUVAIndices(PlanarConfig config,
|
||||
|
||||
bool SkYUVAInfo::HasAlpha(PlanarConfig planarConfig) {
|
||||
switch (planarConfig) {
|
||||
case PlanarConfig::kUnknown: return false;
|
||||
|
||||
case PlanarConfig::kY_U_V_444: return false;
|
||||
case PlanarConfig::kY_U_V_422: return false;
|
||||
case PlanarConfig::kY_U_V_420: return false;
|
||||
@ -247,11 +258,20 @@ SkYUVAInfo::SkYUVAInfo(SkISize dimensions,
|
||||
, fYUVColorSpace(yuvColorSpace)
|
||||
, fOrigin(origin)
|
||||
, fSitingX(sitingX)
|
||||
, fSitingY(sitingY) {}
|
||||
, fSitingY(sitingY) {
|
||||
if (fDimensions.width() <= 0 ||
|
||||
fDimensions.height() <= 0 ||
|
||||
planarConfig == PlanarConfig::kUnknown) {
|
||||
*this = {};
|
||||
SkASSERT(!this->isValid());
|
||||
return;
|
||||
}
|
||||
SkASSERT(this->isValid());
|
||||
}
|
||||
|
||||
size_t SkYUVAInfo::computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
||||
size_t planeSizes[kMaxPlanes]) const {
|
||||
if (fDimensions.isEmpty()) {
|
||||
if (!this->isValid()) {
|
||||
return 0;
|
||||
}
|
||||
SkSafeMath safe;
|
||||
|
@ -80,7 +80,7 @@ SkYUVAPixmapInfo::SkYUVAPixmapInfo(const SkYUVAInfo& yuvaInfo,
|
||||
const SkColorType colorTypes[kMaxPlanes],
|
||||
const size_t rowBytes[kMaxPlanes])
|
||||
: fYUVAInfo(yuvaInfo) {
|
||||
if (yuvaInfo.dimensions().isEmpty()) {
|
||||
if (!yuvaInfo.isValid()) {
|
||||
*this = {};
|
||||
SkASSERT(!this->isValid());
|
||||
return;
|
||||
|
52
src/gpu/GrYUVABackendTextures.cpp
Normal file
52
src/gpu/GrYUVABackendTextures.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/gpu/GrYUVABackendTextures.h"
|
||||
|
||||
static int num_channels(const GrBackendFormat& format) {
|
||||
switch (format.channelMask()) {
|
||||
case kRed_SkColorChannelFlag : return 1;
|
||||
case kAlpha_SkColorChannelFlag: return 1;
|
||||
case kGray_SkColorChannelFlag : return 1;
|
||||
case kRG_SkColorChannelFlags : return 2;
|
||||
case kRGB_SkColorChannelFlags : return 3;
|
||||
case kRGBA_SkColorChannelFlags: return 4;
|
||||
default : return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GrYUVABackendTextures::GrYUVABackendTextures(
|
||||
const SkYUVAInfo& yuvaInfo,
|
||||
const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],
|
||||
GrSurfaceOrigin textureOrigin)
|
||||
: fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
|
||||
if (!fYUVAInfo.isValid()) {
|
||||
return;
|
||||
}
|
||||
SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
|
||||
int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
|
||||
for (int i = 0; i < numPlanes; ++i) {
|
||||
int numRequiredChannels = fYUVAInfo.numChannelsInPlane(i);
|
||||
if (!textures[i].isValid() ||
|
||||
textures[i].dimensions() != planeDimensions[i] ||
|
||||
textures[i].backend() != textures[0].backend() ||
|
||||
num_channels(textures[i].getBackendFormat()) < numRequiredChannels) {
|
||||
*this = {};
|
||||
return;
|
||||
}
|
||||
fTextures[i] = textures[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool GrYUVABackendTextures::toYUVAIndices(SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) const {
|
||||
SkASSERT(indices);
|
||||
uint32_t channelFlags[] = {fTextures[0].getBackendFormat().channelMask(),
|
||||
fTextures[1].getBackendFormat().channelMask(),
|
||||
fTextures[2].getBackendFormat().channelMask(),
|
||||
fTextures[3].getBackendFormat().channelMask()};
|
||||
return fYUVAInfo.toYUVAIndices(channelFlags, indices);
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
#include "include/core/SkYUVASizeInfo.h"
|
||||
#include "include/gpu/GrDirectContext.h"
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "include/gpu/GrYUVABackendTextures.h"
|
||||
#include "src/core/SkAutoPixmapStorage.h"
|
||||
#include "src/core/SkMipmap.h"
|
||||
#include "src/core/SkScopeExit.h"
|
||||
@ -234,6 +235,45 @@ sk_sp<SkImage> SkImage_GpuYUVA::onReinterpretColorSpace(sk_sp<SkColorSpace> newC
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrRecordingContext* context,
|
||||
const GrYUVABackendTextures& yuvaTextures,
|
||||
sk_sp<SkColorSpace> imageColorSpace,
|
||||
TextureReleaseProc textureReleaseProc,
|
||||
ReleaseContext releaseContext) {
|
||||
sk_sp<GrRefCntedCallback> releaseHelper;
|
||||
if (textureReleaseProc) {
|
||||
releaseHelper.reset(new GrRefCntedCallback(textureReleaseProc, releaseContext));
|
||||
}
|
||||
|
||||
SkYUVAIndex yuvaIndices[4];
|
||||
int numTextures;
|
||||
if (!yuvaTextures.toYUVAIndices(yuvaIndices) ||
|
||||
!SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures)) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(numTextures == yuvaTextures.numPlanes());
|
||||
|
||||
GrSurfaceProxyView tempViews[4];
|
||||
if (!SkImage_GpuBase::MakeTempTextureProxies(context,
|
||||
yuvaTextures.textures().data(),
|
||||
numTextures,
|
||||
yuvaIndices,
|
||||
yuvaTextures.textureOrigin(),
|
||||
tempViews,
|
||||
std::move(releaseHelper))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(context),
|
||||
yuvaTextures.yuvaInfo().dimensions(),
|
||||
kNeedNewImageUniqueID,
|
||||
yuvaTextures.yuvaInfo().yuvColorSpace(),
|
||||
tempViews,
|
||||
numTextures,
|
||||
yuvaIndices,
|
||||
imageColorSpace);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrContext* ctx,
|
||||
SkYUVColorSpace colorSpace,
|
||||
const GrBackendTexture yuvaTextures[],
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "include/core/SkColorPriv.h"
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "include/gpu/GrYUVABackendTextures.h"
|
||||
#include "src/codec/SkCodecImageGenerator.h"
|
||||
#include "src/core/SkYUVMath.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
@ -226,30 +227,26 @@ bool LazyYUVImage::ensureYUVImage(GrRecordingContext* rContext, Type type) {
|
||||
if (auto direct = rContext->asDirectContext()) {
|
||||
sk_sp<sk_gpu_test::ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes];
|
||||
GrBackendTexture textures[SkYUVAInfo::kMaxPlanes];
|
||||
uint32_t componentFlags[SkYUVAInfo::kMaxPlanes] = {};
|
||||
for (int i = 0; i < fPixmaps.numPlanes(); ++i) {
|
||||
mbets[i] = sk_gpu_test::ManagedBackendTexture::MakeWithData(
|
||||
direct, fPixmaps.plane(i), GrRenderable::kNo, GrProtected::kNo);
|
||||
if (mbets[i]) {
|
||||
textures[i] = mbets[i]->texture();
|
||||
componentFlags[i] = textures[i].getBackendFormat().channelMask();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SkYUVAIndex indices[SkYUVAIndex::kIndexCount];
|
||||
if (!fPixmaps.yuvaInfo().toYUVAIndices(componentFlags, indices)) {
|
||||
GrYUVABackendTextures yuvaTextures(fPixmaps.yuvaInfo(),
|
||||
textures,
|
||||
kTopLeft_GrSurfaceOrigin);
|
||||
if (!yuvaTextures.isValid()) {
|
||||
return false;
|
||||
}
|
||||
void* relContext =
|
||||
sk_gpu_test::ManagedBackendTexture::MakeYUVAReleaseContext(mbets);
|
||||
fYUVImage[idx] = SkImage::MakeFromYUVATextures(
|
||||
direct,
|
||||
fPixmaps.yuvaInfo().yuvColorSpace(),
|
||||
textures,
|
||||
indices,
|
||||
fPixmaps.yuvaInfo().dimensions(),
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
yuvaTextures,
|
||||
fColorSpace,
|
||||
sk_gpu_test::ManagedBackendTexture::ReleaseProc,
|
||||
relContext);
|
||||
|
Loading…
Reference in New Issue
Block a user