A new way to specify YUVA planar data from SkCodec to SkImage_Lazy
Tunnels through SkImageGenerator as well.
The new SkCodec interface doesn't assume three 8 bit planes.
New SkYUVASpec more clearly defines chroma subsampling and siting of
the planes.
The intent is to use this for other YUVA APIs as well, in particular
SkImage factories in the future.
In this change we convert to the SkYUVASpec to SkYUVASizeInfo
and SkYUVAIndex[4] representation. But the intent is to use
the SkYUVASpec representation throughout the pipeline once
legacy APIs are removed.
orientation GM is replicated to test a variety of chroma
subsampling configs.
Bug: skia:10632
Change-Id: I3fad35752b87cac16c51b24824331f2ae7d458d3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309658
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
diff --git a/tools/gpu/YUVUtils.cpp b/tools/gpu/YUVUtils.cpp
index 143958d..aa02cab 100644
--- a/tools/gpu/YUVUtils.cpp
+++ b/tools/gpu/YUVUtils.cpp
@@ -10,11 +10,47 @@
#include "include/core/SkData.h"
#include "include/gpu/GrRecordingContext.h"
#include "src/codec/SkCodecImageGenerator.h"
+#include "src/core/SkYUVAInfoPriv.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrRecordingContextPriv.h"
namespace sk_gpu_test {
+YUVAPixmaps::YUVAPixmaps(const SkYUVAInfo& yuvaInfo,
+ SkColorType colorTypes[SkYUVAInfo::kMaxPlanes],
+ size_t rowBytes[SkYUVAInfo::kMaxPlanes])
+ : fYUVAInfo(yuvaInfo) {
+ if (yuvaInfo.dimensions().isEmpty()) {
+ return;
+ }
+ SkISize planeDims[SkYUVAInfo::kMaxPlanes];
+ SkImageInfo ii[SkYUVAInfo::kMaxPlanes];
+ size_t planeSizes[SkYUVAInfo::kMaxPlanes];
+ size_t totalBytes = yuvaInfo.computeTotalBytes(rowBytes, planeSizes);
+ int numPlanes = yuvaInfo.expectedPlaneDims(planeDims);
+ for (int i = 0; i < numPlanes; ++i) {
+ ii[i] = SkImageInfo::Make(planeDims[i], colorTypes[i], kPremul_SkAlphaType);
+ if (!ii[i].validRowBytes(rowBytes[i])) {
+ return;
+ }
+ }
+
+ fStorage.reset(new char[totalBytes]);
+ char* addr = fStorage.get();
+ for (int i = 0; i < numPlanes; ++i) {
+ fPlanes[i].reset(ii[i], addr, rowBytes[i]);
+ addr += planeSizes[i];
+ }
+ fIsValid = true;
+}
+
+bool YUVAPixmaps::toLegacy(SkYUVASizeInfo* yuvaSizeInfo, SkYUVAIndex yuvaIndices[4]) {
+ if (!this->isValid()) {
+ return false;
+ }
+ return SkYUVAInfoPriv::InitLegacyInfo(fYUVAInfo, fPlanes, yuvaSizeInfo, yuvaIndices);
+}
+
std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(sk_sp<SkData> data, GrMipmapped mipmapped) {
std::unique_ptr<LazyYUVImage> image(new LazyYUVImage());
if (image->reset(std::move(data), mipmapped)) {
@@ -47,27 +83,23 @@
return false;
}
- if (!codec->queryYUVA8(&fSizeInfo, fComponents, &fColorSpace)) {
+ SkColorType colorTypes[4];
+ size_t rowBytes[4];
+ SkYUVAInfo yuvaInfo;
+ if (!codec->queryYUVAInfo(&yuvaInfo, colorTypes, rowBytes)) {
+ return false;
+ }
+ fPixmaps = YUVAPixmaps(yuvaInfo, colorTypes, rowBytes);
+ if (!fPixmaps.isValid()) {
return false;
}
- fPlaneData.reset(fSizeInfo.computeTotalBytes());
- void* planes[SkYUVASizeInfo::kMaxCount];
- fSizeInfo.computePlanes(fPlaneData.get(), planes);
- if (!codec->getYUVA8Planes(fSizeInfo, fComponents, planes)) {
+ if (!codec->getYUVAPlanes(fPixmaps.planes())) {
return false;
}
- for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
- if (fSizeInfo.fSizes[i].isEmpty()) {
- fPlanes[i].reset();
- } else {
- SkASSERT(planes[i]);
- auto planeInfo = SkImageInfo::Make(fSizeInfo.fSizes[i].fWidth,
- fSizeInfo.fSizes[i].fHeight,
- kGray_8_SkColorType, kOpaque_SkAlphaType, nullptr);
- fPlanes[i].reset(planeInfo, planes[i], fSizeInfo.fWidthBytes[i]);
- }
+ if (!fPixmaps.toLegacy(&fSizeInfo, fComponents)) {
+ return false;
}
// The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
return true;
@@ -82,8 +114,8 @@
}
// Try to make a new YUV image for this context.
fYUVImage = SkImage::MakeFromYUVAPixmaps(rContext->priv().backdoor(),
- fColorSpace,
- fPlanes,
+ fPixmaps.yuvaInfo().yuvColorSpace(),
+ fPixmaps.planes(),
fComponents,
fSizeInfo.fSizes[0],
kTopLeft_GrSurfaceOrigin,