Revert "Move all YUVA image creation in GMs into sk_gpu_test::LazyYUVImage."
This reverts commit db0288d747ae84e8cfb577f70953c1d56eb78110.
Reason for revert: undeclared tuple size
Original change's description:
> Move all YUVA image creation in GMs into sk_gpu_test::LazyYUVImage.
>
> LazyYUVImage now supports making images from a generator and from
> textures. It uses ManagedBackendTexture to manage texture plane
> lifetime via ref-counting.
>
> Adds some supporting utility functions to SkYUVAInfo and
> SkYUVAPixmaps.
>
> Eases transition of forthcoming MakeFromYUVATextures API change.
>
> Bug: skia:10632
>
> Change-Id: I8cfd747c27076d1627da6ea8a169e554a96049e0
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326720
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
TBR=bsalomon@google.com,robertphillips@google.com
Change-Id: Icdfb70f7dadd97eace8f88d5a886d31534102f5f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10632
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327622
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/tools/gpu/YUVUtils.cpp b/tools/gpu/YUVUtils.cpp
index 93c011b..4e8ad24 100644
--- a/tools/gpu/YUVUtils.cpp
+++ b/tools/gpu/YUVUtils.cpp
@@ -7,154 +7,40 @@
#include "tools/gpu/YUVUtils.h"
-#include "include/core/SkColorPriv.h"
#include "include/core/SkData.h"
#include "include/gpu/GrRecordingContext.h"
#include "src/codec/SkCodecImageGenerator.h"
-#include "src/core/SkYUVMath.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrRecordingContextPriv.h"
-#include "tools/gpu/ManagedBackendTexture.h"
-
-namespace {
-
-static SkPMColor convert_yuva_to_rgba(const float mtx[20], uint8_t yuva[4]) {
- uint8_t y = yuva[0];
- uint8_t u = yuva[1];
- uint8_t v = yuva[2];
- uint8_t a = yuva[3];
-
- uint8_t r = SkTPin(SkScalarRoundToInt(mtx[ 0]*y + mtx[ 1]*u + mtx[ 2]*v + mtx[ 4]*255), 0, 255);
- uint8_t g = SkTPin(SkScalarRoundToInt(mtx[ 5]*y + mtx[ 6]*u + mtx[ 7]*v + mtx[ 9]*255), 0, 255);
- uint8_t b = SkTPin(SkScalarRoundToInt(mtx[10]*y + mtx[11]*u + mtx[12]*v + mtx[14]*255), 0, 255);
-
- return SkPremultiplyARGBInline(a, r, g, b);
-}
-
-static uint8_t look_up(float x1, float y1, const SkPixmap& pmap, SkColorChannel channel) {
- SkASSERT(x1 > 0 && x1 < 1.0f);
- SkASSERT(y1 > 0 && y1 < 1.0f);
- int x = SkScalarFloorToInt(x1 * pmap.width());
- int y = SkScalarFloorToInt(y1 * pmap.height());
-
- auto ii = pmap.info().makeColorType(kRGBA_8888_SkColorType).makeWH(1, 1);
- uint32_t pixel;
- SkAssertResult(pmap.readPixels(ii, &pixel, sizeof(pixel), x, y));
- int shift = static_cast<int>(channel) * 8;
- return static_cast<uint8_t>((pixel >> shift) & 0xff);
-}
-
-class Generator : public SkImageGenerator {
-public:
- Generator(SkYUVAPixmaps pixmaps, sk_sp<SkColorSpace> cs)
- : SkImageGenerator(SkImageInfo::Make(pixmaps.yuvaInfo().dimensions(),
- kN32_SkColorType,
- kPremul_SkAlphaType,
- std::move(cs)))
- , fPixmaps(std::move(pixmaps)) {}
-
-protected:
- bool onGetPixels(const SkImageInfo& info,
- void* pixels,
- size_t rowBytes,
- const Options&) override {
- if (kUnknown_SkColorType == fFlattened.colorType()) {
- fFlattened.allocPixels(info);
- SkASSERT(info == this->getInfo());
-
- float mtx[20];
- SkColorMatrix_YUV2RGB(fPixmaps.yuvaInfo().yuvColorSpace(), mtx);
- SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
- SkAssertResult(fPixmaps.toYUVAIndices(yuvaIndices));
-
- for (int y = 0; y < info.height(); ++y) {
- for (int x = 0; x < info.width(); ++x) {
- float x1 = (x + 0.5f) / info.width();
- float y1 = (y + 0.5f) / info.height();
-
- uint8_t yuva[4] = {0, 0, 0, 255};
-
- for (auto c : {SkYUVAIndex::kY_Index,
- SkYUVAIndex::kU_Index,
- SkYUVAIndex::kV_Index}) {
- const auto& pmap = fPixmaps.plane(yuvaIndices[c].fIndex);
- yuva[c] = look_up(x1, y1, pmap, yuvaIndices[c].fChannel);
- }
- if (yuvaIndices[SkYUVAIndex::kA_Index].fIndex >= 0) {
- const auto& pmap =
- fPixmaps.plane(yuvaIndices[SkYUVAIndex::kA_Index].fIndex);
- yuva[3] =
- look_up(x1, y1, pmap, yuvaIndices[SkYUVAIndex::kA_Index].fChannel);
- }
-
- // Making premul here.
- *fFlattened.getAddr32(x, y) = convert_yuva_to_rgba(mtx, yuva);
- }
- }
- }
-
- return fFlattened.readPixels(info, pixels, rowBytes, 0, 0);
- }
-
- bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& types,
- SkYUVAPixmapInfo* info) const override {
- *info = fPixmaps.pixmapsInfo();
- return info->isValid();
- }
-
- bool onGetYUVAPlanes(const SkYUVAPixmaps& pixmaps) override {
- SkASSERT(pixmaps.yuvaInfo() == fPixmaps.yuvaInfo());
- for (int i = 0; i < pixmaps.numPlanes(); ++i) {
- SkASSERT(fPixmaps.plane(i).colorType() == pixmaps.plane(i).colorType());
- SkASSERT(fPixmaps.plane(i).dimensions() == pixmaps.plane(i).dimensions());
- SkASSERT(fPixmaps.plane(i).rowBytes() == pixmaps.plane(i).rowBytes());
- fPixmaps.plane(i).readPixels(pixmaps.plane(i));
- }
- return true;
- }
-
-private:
- SkYUVAPixmaps fPixmaps;
- SkBitmap fFlattened;
-};
-
-} // anonymous namespace
namespace sk_gpu_test {
-std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(sk_sp<SkData> data,
- GrMipmapped mipmapped,
- sk_sp<SkColorSpace> cs) {
+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, std::move(cs))) {
+ if (image->reset(std::move(data), mipmapped)) {
return image;
} else {
return nullptr;
}
}
-std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(SkYUVAPixmaps pixmaps,
- GrMipmapped mipmapped,
- sk_sp<SkColorSpace> cs) {
- std::unique_ptr<LazyYUVImage> image(new LazyYUVImage());
- if (image->reset(std::move(pixmaps), mipmapped, std::move(cs))) {
- return image;
+sk_sp<SkImage> LazyYUVImage::refImage(GrRecordingContext* rContext) {
+ if (this->ensureYUVImage(rContext)) {
+ return fYUVImage;
} else {
return nullptr;
}
}
-sk_sp<SkImage> LazyYUVImage::refImage(GrRecordingContext* rContext, Type type) {
- if (this->ensureYUVImage(rContext, type)) {
- size_t idx = static_cast<size_t>(type);
- SkASSERT(idx >= 0 && idx < SK_ARRAY_COUNT(fYUVImage));
- return fYUVImage[idx];
+const SkImage* LazyYUVImage::getImage(GrRecordingContext* rContext) {
+ if (this->ensureYUVImage(rContext)) {
+ return fYUVImage.get();
} else {
return nullptr;
}
}
-bool LazyYUVImage::reset(sk_sp<SkData> data, GrMipmapped mipmapped, sk_sp<SkColorSpace> cs) {
+bool LazyYUVImage::reset(sk_sp<SkData> data, GrMipmapped mipmapped) {
fMipmapped = mipmapped;
auto codec = SkCodecImageGenerator::MakeFromEncodedCodec(data);
if (!codec) {
@@ -174,87 +60,78 @@
return false;
}
- fColorSpace = std::move(cs);
-
- // The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
- return true;
-}
-
-bool LazyYUVImage::reset(SkYUVAPixmaps pixmaps, GrMipmapped mipmapped, sk_sp<SkColorSpace> cs) {
- if (!pixmaps.isValid()) {
+ if (!fPixmaps.toLegacy(&fSizeInfo, fComponents)) {
return false;
}
- fMipmapped = mipmapped;
- if (pixmaps.ownsStorage()) {
- fPixmaps = std::move(pixmaps);
- } else {
- fPixmaps = SkYUVAPixmaps::MakeCopy(std::move(pixmaps));
- }
- fColorSpace = std::move(cs);
// The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
return true;
}
-bool LazyYUVImage::ensureYUVImage(GrRecordingContext* rContext, Type type) {
- size_t idx = static_cast<size_t>(type);
- SkASSERT(idx >= 0 && idx < SK_ARRAY_COUNT(fYUVImage));
- if (fYUVImage[idx] && fYUVImage[idx]->isValid(rContext)) {
- return true; // Have already made a YUV image valid for this context.
+bool LazyYUVImage::ensureYUVImage(GrRecordingContext* rContext) {
+ if (!rContext) {
+ return false; // Cannot make a YUV image from planes
+ }
+ if (fYUVImage && fYUVImage->isValid(rContext)) {
+ return true; // Have already made a YUV image valid for this context.
}
// Try to make a new YUV image for this context.
- switch (type) {
- case Type::kFromPixmaps:
- if (!rContext || rContext->abandoned()) {
- return false;
- }
- fYUVImage[idx] = SkImage::MakeFromYUVAPixmaps(rContext,
- fPixmaps,
- fMipmapped,
- /*limit to max tex size*/ false,
- fColorSpace);
- break;
- case Type::kFromGenerator: {
- // Make sure the generator has ownership of its backing planes.
- auto generator = std::make_unique<Generator>(fPixmaps, fColorSpace);
- fYUVImage[idx] = SkImage::MakeFromGenerator(std::move(generator));
- break;
- }
- case Type::kFromTextures:
- if (!rContext || rContext->abandoned()) {
- return false;
- }
- 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)) {
- 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,
- fColorSpace,
- sk_gpu_test::ManagedBackendTexture::ReleaseProc,
- relContext);
- }
- }
- return fYUVImage[idx] != nullptr;
+ fYUVImage = SkImage::MakeFromYUVAPixmaps(rContext, fPixmaps, fMipmapped, false, nullptr);
+ return fYUVImage != nullptr;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void YUVABackendReleaseContext::Unwind(GrDirectContext* dContext,
+ YUVABackendReleaseContext* beContext,
+ bool fullFlush) {
+
+ // Some backends (e.g., Vulkan) require that all work associated w/ texture
+ // creation be completed before deleting the textures.
+ if (fullFlush) {
+ // If the release context client performed some operations other than backend texture
+ // creation then we may require a full flush to ensure that all the work is completed.
+ dContext->flush();
+ dContext->submit(true);
+ } else {
+ dContext->submit();
+
+ while (!beContext->creationCompleted()) {
+ dContext->checkAsyncWorkCompletion();
+ }
+ }
+
+ delete beContext;
+}
+
+YUVABackendReleaseContext::YUVABackendReleaseContext(GrDirectContext* dContext)
+ : fDContext(dContext) {
+}
+
+YUVABackendReleaseContext::~YUVABackendReleaseContext() {
+ for (int i = 0; i < 4; ++i) {
+ if (fBETextures[i].isValid()) {
+ SkASSERT(fCreationComplete[i]);
+ fDContext->deleteBackendTexture(fBETextures[i]);
+ }
+ }
+}
+
+template<int I> static void CreationComplete(void* releaseContext) {
+ auto beContext = reinterpret_cast<YUVABackendReleaseContext*>(releaseContext);
+ beContext->setCreationComplete(I);
+}
+
+GrGpuFinishedProc YUVABackendReleaseContext::CreationCompleteProc(int index) {
+ SkASSERT(index >= 0 && index < 4);
+
+ switch (index) {
+ case 0: return CreationComplete<0>;
+ case 1: return CreationComplete<1>;
+ case 2: return CreationComplete<2>;
+ case 3: return CreationComplete<3>;
+ }
+
+ SK_ABORT("Invalid YUVA Index.");
+ return nullptr;
+}
+
} // namespace sk_gpu_test