Implement more SkImage_GpuYUVA functionality
Bug: skia:7901 Change-Id: I78a947edb924e0a1240537a83aa0bc111239e567 Reviewed-on: https://skia-review.googlesource.com/c/159320 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
5959353a31
commit
8026ccc46e
@ -544,8 +544,8 @@ skia_gpu_sources = [
|
|||||||
|
|
||||||
"$_src/image/SkImage_Gpu.h",
|
"$_src/image/SkImage_Gpu.h",
|
||||||
"$_src/image/SkImage_Gpu.cpp",
|
"$_src/image/SkImage_Gpu.cpp",
|
||||||
"$_src/image/SkImage_GpuShared.h",
|
"$_src/image/SkImage_GpuBase.h",
|
||||||
"$_src/image/SkImage_GpuShared.cpp",
|
"$_src/image/SkImage_GpuBase.cpp",
|
||||||
"$_src/image/SkImage_GpuYUVA.h",
|
"$_src/image/SkImage_GpuYUVA.h",
|
||||||
"$_src/image/SkImage_GpuYUVA.cpp",
|
"$_src/image/SkImage_GpuYUVA.cpp",
|
||||||
"$_src/image/SkSurface_Gpu.h",
|
"$_src/image/SkSurface_Gpu.h",
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include "SkGr.h"
|
#include "SkGr.h"
|
||||||
#include "SkImageInfoPriv.h"
|
#include "SkImageInfoPriv.h"
|
||||||
#include "SkImage_Gpu.h"
|
#include "SkImage_Gpu.h"
|
||||||
#include "SkImage_GpuShared.h"
|
|
||||||
#include "SkMipMap.h"
|
#include "SkMipMap.h"
|
||||||
#include "SkPixelRef.h"
|
#include "SkPixelRef.h"
|
||||||
#include "SkReadPixelsRec.h"
|
#include "SkReadPixelsRec.h"
|
||||||
@ -46,17 +45,12 @@
|
|||||||
#include "effects/GrYUVtoRGBEffect.h"
|
#include "effects/GrYUVtoRGBEffect.h"
|
||||||
#include "gl/GrGLTexture.h"
|
#include "gl/GrGLTexture.h"
|
||||||
|
|
||||||
using namespace SkImage_GpuShared;
|
|
||||||
|
|
||||||
SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
|
SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
|
||||||
sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace,
|
sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace,
|
||||||
SkBudgeted budgeted)
|
SkBudgeted budgeted)
|
||||||
: INHERITED(proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID)
|
: INHERITED(std::move(context), proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID,
|
||||||
, fContext(std::move(context))
|
at, budgeted, colorSpace)
|
||||||
, fProxy(std::move(proxy))
|
, fProxy(std::move(proxy)) {}
|
||||||
, fAlphaType(at)
|
|
||||||
, fBudgeted(budgeted)
|
|
||||||
, fColorSpace(std::move(colorSpace)) {}
|
|
||||||
|
|
||||||
SkImage_Gpu::~SkImage_Gpu() {}
|
SkImage_Gpu::~SkImage_Gpu() {}
|
||||||
|
|
||||||
@ -69,66 +63,6 @@ SkImageInfo SkImage_Gpu::onImageInfo() const {
|
|||||||
return SkImageInfo::Make(fProxy->width(), fProxy->height(), colorType, fAlphaType, fColorSpace);
|
return SkImageInfo::Make(fProxy->width(), fProxy->height(), colorType, fAlphaType, fColorSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace*, CachingHint chint) const {
|
|
||||||
if (!fContext->contextPriv().resourceProvider()) {
|
|
||||||
// DDL TODO: buffer up the readback so it occurs when the DDL is drawn?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The SkColorSpace parameter "dstColorSpace" is really just a hint about how/where the bitmap
|
|
||||||
// will be used. The client doesn't expect that we convert to that color space, it's intended
|
|
||||||
// for codec-backed images, to drive our decoding heuristic. In theory we *could* read directly
|
|
||||||
// into that color space (to save the client some effort in whatever they're about to do), but
|
|
||||||
// that would make our use of the bitmap cache incorrect (or much less efficient, assuming we
|
|
||||||
// rolled the dstColorSpace into the key).
|
|
||||||
const auto desc = SkBitmapCacheDesc::Make(this);
|
|
||||||
if (SkBitmapCache::Find(desc, dst)) {
|
|
||||||
SkASSERT(dst->getGenerationID() == this->uniqueID());
|
|
||||||
SkASSERT(dst->isImmutable());
|
|
||||||
SkASSERT(dst->getPixels());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkBitmapCache::RecPtr rec = nullptr;
|
|
||||||
SkPixmap pmap;
|
|
||||||
if (kAllow_CachingHint == chint) {
|
|
||||||
rec = SkBitmapCache::Alloc(desc, this->onImageInfo(), &pmap);
|
|
||||||
if (!rec) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!dst->tryAllocPixels(this->onImageInfo()) || !dst->peekPixels(&pmap)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
|
|
||||||
fProxy,
|
|
||||||
fColorSpace);
|
|
||||||
if (!sContext) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sContext->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), 0, 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec) {
|
|
||||||
SkBitmapCache::Add(std::move(rec), dst);
|
|
||||||
this->notifyAddedToRasterCache();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef(GrContext* context,
|
|
||||||
const GrSamplerState& params,
|
|
||||||
SkColorSpace* dstColorSpace,
|
|
||||||
sk_sp<SkColorSpace>* texColorSpace,
|
|
||||||
SkScalar scaleAdjust[2]) const {
|
|
||||||
return AsTextureProxyRef(context, params, dstColorSpace, texColorSpace, scaleAdjust,
|
|
||||||
fContext.get(), this, fAlphaType, fColorSpace.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||||
switch (info.colorType()) {
|
switch (info.colorType()) {
|
||||||
case kRGBA_8888_SkColorType:
|
case kRGBA_8888_SkColorType:
|
||||||
@ -151,51 +85,6 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrBackendTexture SkImage_Gpu::onGetBackendTexture(bool flushPendingGrContextIO,
|
|
||||||
GrSurfaceOrigin* origin) const {
|
|
||||||
SkASSERT(fProxy);
|
|
||||||
|
|
||||||
if (!fContext->contextPriv().resourceProvider() && !fProxy->isInstantiated()) {
|
|
||||||
// This image was created with a DDL context and cannot be instantiated.
|
|
||||||
return GrBackendTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fProxy->instantiate(fContext->contextPriv().resourceProvider())) {
|
|
||||||
return GrBackendTexture(); // invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
GrTexture* texture = fProxy->peekTexture();
|
|
||||||
|
|
||||||
if (texture) {
|
|
||||||
if (flushPendingGrContextIO) {
|
|
||||||
fContext->contextPriv().prepareSurfaceForExternalIO(fProxy.get());
|
|
||||||
}
|
|
||||||
if (origin) {
|
|
||||||
*origin = fProxy->origin();
|
|
||||||
}
|
|
||||||
return texture->getBackendTexture();
|
|
||||||
}
|
|
||||||
return GrBackendTexture(); // invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
GrTexture* SkImage_Gpu::onGetTexture() const {
|
|
||||||
GrTextureProxy* proxy = this->peekProxy();
|
|
||||||
if (!proxy) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fContext->contextPriv().resourceProvider() && !fProxy->isInstantiated()) {
|
|
||||||
// This image was created with a DDL context and cannot be instantiated.
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!proxy->instantiate(fContext->contextPriv().resourceProvider())) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return proxy->peekTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
|
bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
|
||||||
int srcX, int srcY, CachingHint) const {
|
int srcX, int srcY, CachingHint) const {
|
||||||
if (!fContext->contextPriv().resourceProvider()) {
|
if (!fContext->contextPriv().resourceProvider()) {
|
||||||
@ -275,7 +164,7 @@ sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
GrBackendTexture texCopy = tex;
|
GrBackendTexture texCopy = tex;
|
||||||
if (!ValidateBackendTexture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
|
if (!SkImage_GpuBase::ValidateBackendTexture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return new_wrapped_texture_common(ctx, texCopy, origin, at, std::move(cs),
|
return new_wrapped_texture_common(ctx, texCopy, origin, at, std::move(cs),
|
||||||
@ -291,7 +180,7 @@ sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
GrBackendTexture texCopy = tex;
|
GrBackendTexture texCopy = tex;
|
||||||
if (!ValidateBackendTexture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
|
if (!SkImage_GpuBase::ValidateBackendTexture(ctx, texCopy, &texCopy.fConfig, ct, at, cs)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return new_wrapped_texture_common(ctx, texCopy, origin, at, std::move(cs),
|
return new_wrapped_texture_common(ctx, texCopy, origin, at, std::move(cs),
|
||||||
@ -1129,57 +1018,3 @@ bool SkImage::MakeBackendTextureFromSkImage(GrContext* ctx,
|
|||||||
return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
|
return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
sk_sp<SkImage> SkImage_Gpu::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
|
|
||||||
SkAlphaType newAlphaType = fAlphaType;
|
|
||||||
#if defined(SK_LEGACY_MAKE_COLOR_SPACE_IMPL)
|
|
||||||
if (kUnpremul_SkAlphaType == fAlphaType) {
|
|
||||||
newAlphaType = kPremul_SkAlphaType;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
auto xform = GrColorSpaceXformEffect::Make(fColorSpace.get(), this->alphaType(),
|
|
||||||
target.get(), newAlphaType);
|
|
||||||
if (!xform) {
|
|
||||||
return sk_ref_sp(const_cast<SkImage_Gpu*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<GrRenderTargetContext> renderTargetContext(
|
|
||||||
fContext->contextPriv().makeDeferredRenderTargetContext(
|
|
||||||
SkBackingFit::kExact, this->width(), this->height(),
|
|
||||||
kRGBA_8888_GrPixelConfig, nullptr));
|
|
||||||
if (!renderTargetContext) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrPaint paint;
|
|
||||||
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
|
||||||
paint.addColorTextureProcessor(fProxy, SkMatrix::I());
|
|
||||||
paint.addColorFragmentProcessor(std::move(xform));
|
|
||||||
|
|
||||||
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
|
||||||
|
|
||||||
renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
|
|
||||||
|
|
||||||
if (!renderTargetContext->asTextureProxy()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MDB: this call is okay bc we know 'renderTargetContext' was exact
|
|
||||||
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
|
|
||||||
newAlphaType, renderTargetContext->asTextureProxyRef(),
|
|
||||||
std::move(target), fBudgeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkImage_Gpu::onIsValid(GrContext* context) const {
|
|
||||||
// The base class has already checked that context isn't abandoned (if it's not nullptr)
|
|
||||||
if (fContext->abandoned()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context && context != fContext.get()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -13,15 +13,14 @@
|
|||||||
#include "GrSurfaceProxyPriv.h"
|
#include "GrSurfaceProxyPriv.h"
|
||||||
#include "SkGr.h"
|
#include "SkGr.h"
|
||||||
#include "SkImagePriv.h"
|
#include "SkImagePriv.h"
|
||||||
#include "SkImage_Base.h"
|
#include "SkImage_GpuBase.h"
|
||||||
#include "SkImage_GpuShared.h"
|
|
||||||
|
|
||||||
class GrTexture;
|
class GrTexture;
|
||||||
|
|
||||||
class SkBitmap;
|
class SkBitmap;
|
||||||
struct SkYUVAIndex;
|
struct SkYUVAIndex;
|
||||||
|
|
||||||
class SkImage_Gpu : public SkImage_Base {
|
class SkImage_Gpu : public SkImage_GpuBase {
|
||||||
public:
|
public:
|
||||||
SkImage_Gpu(sk_sp<GrContext>, uint32_t uniqueID, SkAlphaType, sk_sp<GrTextureProxy>,
|
SkImage_Gpu(sk_sp<GrContext>, uint32_t uniqueID, SkAlphaType, sk_sp<GrTextureProxy>,
|
||||||
sk_sp<SkColorSpace>, SkBudgeted);
|
sk_sp<SkColorSpace>, SkBudgeted);
|
||||||
@ -29,40 +28,18 @@ public:
|
|||||||
|
|
||||||
SkImageInfo onImageInfo() const override;
|
SkImageInfo onImageInfo() const override;
|
||||||
|
|
||||||
bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
|
|
||||||
sk_sp<SkImage> onMakeSubset(const SkIRect& subset) const override {
|
|
||||||
return SkImage_GpuShared::OnMakeSubset(subset, fContext, this, fAlphaType, fColorSpace,
|
|
||||||
fBudgeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
GrContext* context() const override { return fContext.get(); }
|
|
||||||
GrTextureProxy* peekProxy() const override {
|
GrTextureProxy* peekProxy() const override {
|
||||||
return fProxy.get();
|
return fProxy.get();
|
||||||
}
|
}
|
||||||
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
|
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
|
||||||
return fProxy;
|
return fProxy;
|
||||||
}
|
}
|
||||||
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerState&, SkColorSpace*,
|
|
||||||
sk_sp<SkColorSpace>*,
|
|
||||||
SkScalar scaleAdjust[2]) const override;
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> refPinnedTextureProxy(uint32_t* uniqueID) const override {
|
|
||||||
*uniqueID = this->uniqueID();
|
|
||||||
return fProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
|
||||||
GrSurfaceOrigin* origin) const override;
|
|
||||||
|
|
||||||
GrTexture* onGetTexture() const override;
|
|
||||||
|
|
||||||
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
||||||
int srcX, int srcY, CachingHint) const override;
|
int srcX, int srcY, CachingHint) const override;
|
||||||
|
|
||||||
sk_sp<SkColorSpace> refColorSpace() { return fColorSpace; }
|
sk_sp<SkColorSpace> refColorSpace() { return fColorSpace; }
|
||||||
|
|
||||||
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override;
|
|
||||||
|
|
||||||
typedef ReleaseContext TextureContext;
|
typedef ReleaseContext TextureContext;
|
||||||
typedef void (*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
|
typedef void (*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
|
||||||
typedef void (*PromiseDoneProc)(TextureContext textureContext);
|
typedef void (*PromiseDoneProc)(TextureContext textureContext);
|
||||||
@ -158,8 +135,6 @@ public:
|
|||||||
const GrBackendTexture backendTexture,
|
const GrBackendTexture backendTexture,
|
||||||
sk_sp<SkColorSpace> imageColorSpace);
|
sk_sp<SkColorSpace> imageColorSpace);
|
||||||
|
|
||||||
bool onIsValid(GrContext*) const override;
|
|
||||||
|
|
||||||
void resetContext(sk_sp<GrContext> newContext) {
|
void resetContext(sk_sp<GrContext> newContext) {
|
||||||
SkASSERT(fContext->uniqueID() == newContext->uniqueID());
|
SkASSERT(fContext->uniqueID() == newContext->uniqueID());
|
||||||
fContext = newContext;
|
fContext = newContext;
|
||||||
@ -171,13 +146,9 @@ private:
|
|||||||
const SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin,
|
const SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin,
|
||||||
SkBudgeted isBudgeted, GrRenderTargetContext* renderTargetContext);
|
SkBudgeted isBudgeted, GrRenderTargetContext* renderTargetContext);
|
||||||
|
|
||||||
sk_sp<GrContext> fContext;
|
|
||||||
sk_sp<GrTextureProxy> fProxy;
|
sk_sp<GrTextureProxy> fProxy;
|
||||||
const SkAlphaType fAlphaType;
|
|
||||||
const SkBudgeted fBudgeted;
|
|
||||||
sk_sp<SkColorSpace> fColorSpace;
|
|
||||||
|
|
||||||
typedef SkImage_Base INHERITED;
|
typedef SkImage_GpuBase INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
237
src/image/SkImage_GpuBase.cpp
Normal file
237
src/image/SkImage_GpuBase.cpp
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GrBackendSurface.h"
|
||||||
|
#include "GrClip.h"
|
||||||
|
#include "GrContext.h"
|
||||||
|
#include "GrContextPriv.h"
|
||||||
|
#include "GrRenderTargetContext.h"
|
||||||
|
#include "GrTexture.h"
|
||||||
|
#include "GrTextureAdjuster.h"
|
||||||
|
#include "SkBitmapCache.h"
|
||||||
|
#include "SkImage_Gpu.h"
|
||||||
|
#include "SkImage_GpuBase.h"
|
||||||
|
|
||||||
|
SkImage_GpuBase::SkImage_GpuBase(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
|
||||||
|
SkAlphaType at, SkBudgeted budgeted, sk_sp<SkColorSpace> cs)
|
||||||
|
: INHERITED(width, height, uniqueID)
|
||||||
|
, fContext(std::move(context))
|
||||||
|
, fAlphaType(at)
|
||||||
|
, fBudgeted(budgeted)
|
||||||
|
, fColorSpace(std::move(cs)) {}
|
||||||
|
|
||||||
|
SkImage_GpuBase::~SkImage_GpuBase() {}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool SkImage_GpuBase::ValidateBackendTexture(GrContext* ctx, const GrBackendTexture& tex,
|
||||||
|
GrPixelConfig* config, SkColorType ct, SkAlphaType at,
|
||||||
|
sk_sp<SkColorSpace> cs) {
|
||||||
|
if (!tex.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO: Create a SkImageColorInfo struct for color, alpha, and color space so we don't need to
|
||||||
|
// create a fake image info here.
|
||||||
|
SkImageInfo info = SkImageInfo::Make(1, 1, ct, at, cs);
|
||||||
|
if (!SkImageInfoIsValid(info)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->contextPriv().caps()->validateBackendTexture(tex, ct, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool SkImage_GpuBase::getROPixels(SkBitmap* dst, SkColorSpace*, CachingHint chint) const {
|
||||||
|
if (!fContext->contextPriv().resourceProvider()) {
|
||||||
|
// DDL TODO: buffer up the readback so it occurs when the DDL is drawn?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The SkColorSpace parameter "dstColorSpace" is really just a hint about how/where the bitmap
|
||||||
|
// will be used. The client doesn't expect that we convert to that color space, it's intended
|
||||||
|
// for codec-backed images, to drive our decoding heuristic. In theory we *could* read directly
|
||||||
|
// into that color space (to save the client some effort in whatever they're about to do), but
|
||||||
|
// that would make our use of the bitmap cache incorrect (or much less efficient, assuming we
|
||||||
|
// rolled the dstColorSpace into the key).
|
||||||
|
const auto desc = SkBitmapCacheDesc::Make(this);
|
||||||
|
if (SkBitmapCache::Find(desc, dst)) {
|
||||||
|
SkASSERT(dst->getGenerationID() == this->uniqueID());
|
||||||
|
SkASSERT(dst->isImmutable());
|
||||||
|
SkASSERT(dst->getPixels());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkBitmapCache::RecPtr rec = nullptr;
|
||||||
|
SkPixmap pmap;
|
||||||
|
if (kAllow_CachingHint == chint) {
|
||||||
|
rec = SkBitmapCache::Alloc(desc, this->onImageInfo(), &pmap);
|
||||||
|
if (!rec) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!dst->tryAllocPixels(this->onImageInfo()) || !dst->peekPixels(&pmap)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
|
||||||
|
this->asTextureProxyRef(),
|
||||||
|
fColorSpace);
|
||||||
|
if (!sContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sContext->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), 0, 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec) {
|
||||||
|
SkBitmapCache::Add(std::move(rec), dst);
|
||||||
|
this->notifyAddedToRasterCache();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<SkImage> SkImage_GpuBase::onMakeSubset(const SkIRect& subset) const {
|
||||||
|
sk_sp<GrSurfaceProxy> proxy = this->asTextureProxyRef();
|
||||||
|
|
||||||
|
GrSurfaceDesc desc;
|
||||||
|
desc.fWidth = subset.width();
|
||||||
|
desc.fHeight = subset.height();
|
||||||
|
desc.fConfig = proxy->config();
|
||||||
|
|
||||||
|
sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
|
||||||
|
desc, proxy->origin(), GrMipMapped::kNo, SkBackingFit::kExact, fBudgeted));
|
||||||
|
if (!sContext) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sContext->copy(proxy.get(), subset, SkIPoint::Make(0, 0))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MDB: this call is okay bc we know 'sContext' was kExact
|
||||||
|
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
|
||||||
|
fAlphaType, sContext->asTextureProxyRef(),
|
||||||
|
fColorSpace, fBudgeted);
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<GrTextureProxy> SkImage_GpuBase::asTextureProxyRef(GrContext* context,
|
||||||
|
const GrSamplerState& params,
|
||||||
|
SkColorSpace* dstColorSpace,
|
||||||
|
sk_sp<SkColorSpace>* texColorSpace,
|
||||||
|
SkScalar scaleAdjust[2]) const {
|
||||||
|
if (context->uniqueID() != fContext->uniqueID()) {
|
||||||
|
SkASSERT(0);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrTextureAdjuster adjuster(fContext.get(), this->asTextureProxyRef(), fAlphaType,
|
||||||
|
this->uniqueID(), fColorSpace.get());
|
||||||
|
return adjuster.refTextureProxyForParams(params, dstColorSpace, texColorSpace, scaleAdjust);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrBackendTexture SkImage_GpuBase::onGetBackendTexture(bool flushPendingGrContextIO,
|
||||||
|
GrSurfaceOrigin* origin) const {
|
||||||
|
sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef();
|
||||||
|
SkASSERT(proxy);
|
||||||
|
|
||||||
|
if (!fContext->contextPriv().resourceProvider() && !proxy->isInstantiated()) {
|
||||||
|
// This image was created with a DDL context and cannot be instantiated.
|
||||||
|
return GrBackendTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxy->instantiate(fContext->contextPriv().resourceProvider())) {
|
||||||
|
return GrBackendTexture(); // invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
GrTexture* texture = proxy->peekTexture();
|
||||||
|
|
||||||
|
if (texture) {
|
||||||
|
if (flushPendingGrContextIO) {
|
||||||
|
fContext->contextPriv().prepareSurfaceForExternalIO(proxy.get());
|
||||||
|
}
|
||||||
|
if (origin) {
|
||||||
|
*origin = proxy->origin();
|
||||||
|
}
|
||||||
|
return texture->getBackendTexture();
|
||||||
|
}
|
||||||
|
return GrBackendTexture(); // invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
GrTexture* SkImage_GpuBase::onGetTexture() const {
|
||||||
|
GrTextureProxy* proxy = this->peekProxy();
|
||||||
|
if (!proxy) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<GrTextureProxy> proxyRef = this->asTextureProxyRef();
|
||||||
|
if (!fContext->contextPriv().resourceProvider() && !proxyRef->isInstantiated()) {
|
||||||
|
// This image was created with a DDL context and cannot be instantiated.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxy->instantiate(fContext->contextPriv().resourceProvider())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy->peekTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<SkImage> SkImage_GpuBase::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
|
||||||
|
SkAlphaType newAlphaType = fAlphaType;
|
||||||
|
#if defined(SK_LEGACY_MAKE_COLOR_SPACE_IMPL)
|
||||||
|
if (kUnpremul_SkAlphaType == fAlphaType) {
|
||||||
|
newAlphaType = kPremul_SkAlphaType;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
auto xform = GrColorSpaceXformEffect::Make(fColorSpace.get(), this->alphaType(),
|
||||||
|
target.get(), newAlphaType);
|
||||||
|
if (!xform) {
|
||||||
|
return sk_ref_sp(const_cast<SkImage_GpuBase*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<GrRenderTargetContext> renderTargetContext(
|
||||||
|
fContext->contextPriv().makeDeferredRenderTargetContext(
|
||||||
|
SkBackingFit::kExact, this->width(), this->height(),
|
||||||
|
kRGBA_8888_GrPixelConfig, nullptr));
|
||||||
|
if (!renderTargetContext) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrPaint paint;
|
||||||
|
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
||||||
|
paint.addColorTextureProcessor(this->asTextureProxyRef(), SkMatrix::I());
|
||||||
|
paint.addColorFragmentProcessor(std::move(xform));
|
||||||
|
|
||||||
|
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
||||||
|
|
||||||
|
renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
|
||||||
|
|
||||||
|
if (!renderTargetContext->asTextureProxy()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MDB: this call is okay bc we know 'renderTargetContext' was exact
|
||||||
|
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
|
||||||
|
newAlphaType, renderTargetContext->asTextureProxyRef(),
|
||||||
|
std::move(target), fBudgeted);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkImage_GpuBase::onIsValid(GrContext* context) const {
|
||||||
|
// The base class has already checked that context isn't abandoned (if it's not nullptr)
|
||||||
|
if (fContext->abandoned()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context && context != fContext.get()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
63
src/image/SkImage_GpuBase.h
Normal file
63
src/image/SkImage_GpuBase.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SkImage_GpuBase_DEFINED
|
||||||
|
#define SkImage_GpuBase_DEFINED
|
||||||
|
|
||||||
|
#include "SkImage_Base.h"
|
||||||
|
|
||||||
|
class GrContext;
|
||||||
|
class SkColorSpace;
|
||||||
|
|
||||||
|
class SkImage_GpuBase : public SkImage_Base {
|
||||||
|
public:
|
||||||
|
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID,
|
||||||
|
SkAlphaType, SkBudgeted, sk_sp<SkColorSpace>);
|
||||||
|
~SkImage_GpuBase() override;
|
||||||
|
|
||||||
|
GrContext* context() const final { return fContext.get(); }
|
||||||
|
|
||||||
|
bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const final;
|
||||||
|
sk_sp<SkImage> onMakeSubset(const SkIRect& subset) const final;
|
||||||
|
|
||||||
|
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
|
||||||
|
// we shouldn't end up calling this
|
||||||
|
SkASSERT(false);
|
||||||
|
return this->INHERITED::asTextureProxyRef();
|
||||||
|
}
|
||||||
|
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerState&, SkColorSpace*,
|
||||||
|
sk_sp<SkColorSpace>*,
|
||||||
|
SkScalar scaleAdjust[2]) const final;
|
||||||
|
|
||||||
|
sk_sp<GrTextureProxy> refPinnedTextureProxy(uint32_t* uniqueID) const final {
|
||||||
|
*uniqueID = this->uniqueID();
|
||||||
|
return this->asTextureProxyRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
||||||
|
GrSurfaceOrigin* origin) const final;
|
||||||
|
|
||||||
|
GrTexture* onGetTexture() const final;
|
||||||
|
|
||||||
|
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const final;
|
||||||
|
|
||||||
|
bool onIsValid(GrContext*) const final;
|
||||||
|
|
||||||
|
static bool ValidateBackendTexture(GrContext* ctx, const GrBackendTexture& tex,
|
||||||
|
GrPixelConfig* config, SkColorType ct, SkAlphaType at,
|
||||||
|
sk_sp<SkColorSpace> cs);
|
||||||
|
protected:
|
||||||
|
sk_sp<GrContext> fContext;
|
||||||
|
const SkAlphaType fAlphaType; // alpha type for final image
|
||||||
|
const SkBudgeted fBudgeted;
|
||||||
|
sk_sp<SkColorSpace> fColorSpace; // color space for final image
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef SkImage_Base INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "GrBackendSurface.h"
|
|
||||||
#include "GrContext.h"
|
|
||||||
#include "GrContextPriv.h"
|
|
||||||
#include "GrTextureAdjuster.h"
|
|
||||||
#include "SkImage_Gpu.h"
|
|
||||||
#include "SkImage_GpuShared.h"
|
|
||||||
|
|
||||||
namespace SkImage_GpuShared {
|
|
||||||
|
|
||||||
bool ValidateBackendTexture(GrContext* ctx, const GrBackendTexture& tex,
|
|
||||||
GrPixelConfig* config, SkColorType ct, SkAlphaType at,
|
|
||||||
sk_sp<SkColorSpace> cs) {
|
|
||||||
if (!tex.isValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO: Create a SkImageColorInfo struct for color, alpha, and color space so we don't need to
|
|
||||||
// create a fake image info here.
|
|
||||||
SkImageInfo info = SkImageInfo::Make(1, 1, ct, at, cs);
|
|
||||||
if (!SkImageInfoIsValid(info)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx->contextPriv().caps()->validateBackendTexture(tex, ct, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> AsTextureProxyRef(GrContext* context,
|
|
||||||
const GrSamplerState& params,
|
|
||||||
SkColorSpace* dstColorSpace,
|
|
||||||
sk_sp<SkColorSpace>* texColorSpace,
|
|
||||||
SkScalar scaleAdjust[2],
|
|
||||||
GrContext* imageContext,
|
|
||||||
const SkImage_Base* image,
|
|
||||||
const SkAlphaType imageAlphaType,
|
|
||||||
SkColorSpace* imageColorSpace) {
|
|
||||||
if (context->uniqueID() != imageContext->uniqueID()) {
|
|
||||||
SkASSERT(0);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrTextureAdjuster adjuster(imageContext, image->asTextureProxyRef(), imageAlphaType,
|
|
||||||
image->uniqueID(), imageColorSpace);
|
|
||||||
return adjuster.refTextureProxyForParams(params, dstColorSpace, texColorSpace, scaleAdjust);
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<SkImage> OnMakeSubset(const SkIRect& subset, sk_sp<GrContext> imageContext,
|
|
||||||
const SkImage_Base* image, const SkAlphaType imageAlphaType,
|
|
||||||
sk_sp<SkColorSpace> imageColorSpace, const SkBudgeted budgeted){
|
|
||||||
sk_sp<GrSurfaceProxy> proxy = image->asTextureProxyRef();
|
|
||||||
|
|
||||||
GrSurfaceDesc desc;
|
|
||||||
desc.fWidth = subset.width();
|
|
||||||
desc.fHeight = subset.height();
|
|
||||||
desc.fConfig = proxy->config();
|
|
||||||
|
|
||||||
sk_sp<GrSurfaceContext> sContext(imageContext->contextPriv().makeDeferredSurfaceContext(
|
|
||||||
desc, proxy->origin(), GrMipMapped::kNo, SkBackingFit::kExact, budgeted));
|
|
||||||
if (!sContext) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sContext->copy(proxy.get(), subset, SkIPoint::Make(0, 0))) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MDB: this call is okay bc we know 'sContext' was kExact
|
|
||||||
return sk_make_sp<SkImage_Gpu>(imageContext, kNeedNewImageUniqueID,
|
|
||||||
imageAlphaType, sContext->asTextureProxyRef(),
|
|
||||||
imageColorSpace, budgeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SkImage_GpuShared_DEFINED
|
|
||||||
#define SkImage_GpuShared_DEFINED
|
|
||||||
|
|
||||||
#include "SkImageInfo.h"
|
|
||||||
#include "SkTypes.h"
|
|
||||||
|
|
||||||
class GrContext;
|
|
||||||
class SkImage_Base;
|
|
||||||
|
|
||||||
namespace SkImage_GpuShared {
|
|
||||||
|
|
||||||
bool ValidateBackendTexture(GrContext* ctx, const GrBackendTexture& tex,
|
|
||||||
GrPixelConfig* config, SkColorType ct, SkAlphaType at,
|
|
||||||
sk_sp<SkColorSpace> cs);
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> AsTextureProxyRef(GrContext* context,
|
|
||||||
const GrSamplerState& params,
|
|
||||||
SkColorSpace* dstColorSpace,
|
|
||||||
sk_sp<SkColorSpace>* texColorSpace,
|
|
||||||
SkScalar scaleAdjust[2],
|
|
||||||
GrContext* imageContext,
|
|
||||||
const SkImage_Base* image,
|
|
||||||
const SkAlphaType imageAlphaType,
|
|
||||||
SkColorSpace* imageColorSpace);
|
|
||||||
|
|
||||||
sk_sp<SkImage> OnMakeSubset(const SkIRect& subset, sk_sp<GrContext> imageContext,
|
|
||||||
const SkImage_Base* image, const SkAlphaType imageAlphaType,
|
|
||||||
sk_sp<SkColorSpace> imageColorSpace, const SkBudgeted budgeted);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -16,33 +16,27 @@
|
|||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
#include "GrTextureAdjuster.h"
|
#include "GrTextureAdjuster.h"
|
||||||
#include "SkImage_Gpu.h"
|
#include "SkImage_Gpu.h"
|
||||||
#include "SkImage_GpuShared.h"
|
|
||||||
#include "SkImage_GpuYUVA.h"
|
#include "SkImage_GpuYUVA.h"
|
||||||
#include "SkReadPixelsRec.h"
|
#include "SkReadPixelsRec.h"
|
||||||
#include "effects/GrYUVtoRGBEffect.h"
|
#include "effects/GrYUVtoRGBEffect.h"
|
||||||
|
|
||||||
using namespace SkImage_GpuShared;
|
|
||||||
|
|
||||||
SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, uint32_t uniqueID,
|
SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, uint32_t uniqueID,
|
||||||
SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
|
SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
|
||||||
SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin,
|
SkYUVAIndex yuvaIndices[4], SkISize size, GrSurfaceOrigin origin,
|
||||||
sk_sp<SkColorSpace> imageColorSpace, SkBudgeted budgeted)
|
sk_sp<SkColorSpace> imageColorSpace, SkBudgeted budgeted)
|
||||||
: INHERITED(size.width(), size.height(), uniqueID)
|
: INHERITED(std::move(context), size.width(), size.height(), uniqueID,
|
||||||
, fContext(std::move(context))
|
// If an alpha channel is present we always switch to kPremul. This is because,
|
||||||
, fBudgeted(budgeted)
|
// although the planar data is always un-premul, the final interleaved RGB image
|
||||||
, fColorSpace(colorSpace)
|
// is/would-be premul.
|
||||||
, fOrigin(origin)
|
-1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex ? kPremul_SkAlphaType
|
||||||
, fImageAlphaType(kOpaque_SkAlphaType)
|
: kOpaque_SkAlphaType,
|
||||||
, fImageColorSpace(std::move(imageColorSpace)) {
|
budgeted, imageColorSpace)
|
||||||
|
, fYUVColorSpace(colorSpace)
|
||||||
|
, fOrigin(origin) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
fProxies[i] = std::move(proxies[i]);
|
fProxies[i] = std::move(proxies[i]);
|
||||||
}
|
}
|
||||||
memcpy(fYUVAIndices, yuvaIndices, 4*sizeof(SkYUVAIndex));
|
memcpy(fYUVAIndices, yuvaIndices, 4*sizeof(SkYUVAIndex));
|
||||||
// If an alpha channel is present we always switch to kPremul. This is because, although the
|
|
||||||
// planar data is always un-premul, the final interleaved RGB image is/would-be premul.
|
|
||||||
if (-1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex) {
|
|
||||||
fImageAlphaType = kPremul_SkAlphaType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
|
SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
|
||||||
@ -50,7 +44,7 @@ SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
|
|||||||
SkImageInfo SkImage_GpuYUVA::onImageInfo() const {
|
SkImageInfo SkImage_GpuYUVA::onImageInfo() const {
|
||||||
// Note: this is the imageInfo for the flattened image, not the YUV planes
|
// Note: this is the imageInfo for the flattened image, not the YUV planes
|
||||||
return SkImageInfo::Make(this->width(), this->height(), kRGBA_8888_SkColorType,
|
return SkImageInfo::Make(this->width(), this->height(), kRGBA_8888_SkColorType,
|
||||||
fImageAlphaType, fImageColorSpace);
|
fAlphaType, fColorSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -73,7 +67,7 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef() const {
|
|||||||
fYUVAIndices[SkYUVAIndex::kV_Index].fIndex);
|
fYUVAIndices[SkYUVAIndex::kV_Index].fIndex);
|
||||||
// TODO: modify the YUVtoRGBEffect to do premul if fImageAlphaType is kPremul_AlphaType
|
// TODO: modify the YUVtoRGBEffect to do premul if fImageAlphaType is kPremul_AlphaType
|
||||||
paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Make(std::move(yProxy), std::move(uProxy),
|
paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Make(std::move(yProxy), std::move(uProxy),
|
||||||
std::move(vProxy), fColorSpace,
|
std::move(vProxy), fYUVColorSpace,
|
||||||
nv12));
|
nv12));
|
||||||
|
|
||||||
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
||||||
@ -82,7 +76,7 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef() const {
|
|||||||
sk_sp<GrRenderTargetContext> renderTargetContext(
|
sk_sp<GrRenderTargetContext> renderTargetContext(
|
||||||
fContext->contextPriv().makeDeferredRenderTargetContext(
|
fContext->contextPriv().makeDeferredRenderTargetContext(
|
||||||
SkBackingFit::kExact, this->width(), this->height(), kRGBA_8888_GrPixelConfig,
|
SkBackingFit::kExact, this->width(), this->height(), kRGBA_8888_GrPixelConfig,
|
||||||
std::move(fImageColorSpace), 1, GrMipMapped::kNo, fOrigin));
|
std::move(fColorSpace), 1, GrMipMapped::kNo, fOrigin));
|
||||||
if (!renderTargetContext) {
|
if (!renderTargetContext) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -102,15 +96,6 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef() const {
|
|||||||
return fRGBProxy;
|
return fRGBProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef(GrContext* context,
|
|
||||||
const GrSamplerState& params,
|
|
||||||
SkColorSpace* dstColorSpace,
|
|
||||||
sk_sp<SkColorSpace>* texColorSpace,
|
|
||||||
SkScalar scaleAdjust[2]) const {
|
|
||||||
return AsTextureProxyRef(context, params, dstColorSpace, texColorSpace, scaleAdjust,
|
|
||||||
fContext.get(), this, fImageAlphaType, fImageColorSpace.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkImage_GpuYUVA::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
|
bool SkImage_GpuYUVA::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
|
||||||
int srcX, int srcY, CachingHint) const {
|
int srcX, int srcY, CachingHint) const {
|
||||||
if (!fContext->contextPriv().resourceProvider()) {
|
if (!fContext->contextPriv().resourceProvider()) {
|
||||||
@ -133,13 +118,13 @@ bool SkImage_GpuYUVA::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
|
|||||||
// TODO: this seems to duplicate code in GrTextureContext::onReadPixels and
|
// TODO: this seems to duplicate code in GrTextureContext::onReadPixels and
|
||||||
// GrRenderTargetContext::onReadPixels
|
// GrRenderTargetContext::onReadPixels
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() && kPremul_SkAlphaType == fImageAlphaType) {
|
if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() && kPremul_SkAlphaType == fAlphaType) {
|
||||||
// let the GPU perform this transformation for us
|
// let the GPU perform this transformation for us
|
||||||
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
|
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
|
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
|
||||||
proxy, fImageColorSpace);
|
proxy, fColorSpace);
|
||||||
if (!sContext) {
|
if (!sContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "GrBackendSurface.h"
|
#include "GrBackendSurface.h"
|
||||||
#include "GrContext.h"
|
#include "GrContext.h"
|
||||||
#include "SkCachedData.h"
|
#include "SkCachedData.h"
|
||||||
#include "SkImage_Base.h"
|
#include "SkImage_GpuBase.h"
|
||||||
#include "SkYUVAIndex.h"
|
#include "SkYUVAIndex.h"
|
||||||
|
|
||||||
class GrTexture;
|
class GrTexture;
|
||||||
@ -20,7 +20,7 @@ class GrTexture;
|
|||||||
// Initially any direct rendering will be done by passing the individual planes to a shader.
|
// Initially any direct rendering will be done by passing the individual planes to a shader.
|
||||||
// Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB
|
// Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB
|
||||||
// proxy will be stored and used for any future rendering.
|
// proxy will be stored and used for any future rendering.
|
||||||
class SkImage_GpuYUVA : public SkImage_Base {
|
class SkImage_GpuYUVA : public SkImage_GpuBase {
|
||||||
public:
|
public:
|
||||||
SkImage_GpuYUVA(sk_sp<GrContext>, uint32_t uniqueID, SkYUVColorSpace,
|
SkImage_GpuYUVA(sk_sp<GrContext>, uint32_t uniqueID, SkYUVColorSpace,
|
||||||
sk_sp<GrTextureProxy> proxies[], SkYUVAIndex yuvaIndices[4], SkISize size,
|
sk_sp<GrTextureProxy> proxies[], SkYUVAIndex yuvaIndices[4], SkISize size,
|
||||||
@ -29,31 +29,8 @@ public:
|
|||||||
|
|
||||||
SkImageInfo onImageInfo() const override;
|
SkImageInfo onImageInfo() const override;
|
||||||
|
|
||||||
bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override {
|
GrTextureProxy* peekProxy() const override { return this->asTextureProxyRef().get(); }
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sk_sp<SkImage> onMakeSubset(const SkIRect& subset) const override {
|
|
||||||
return SkImage_GpuShared::OnMakeSubset(subset, fContext, this, fImageAlphaType,
|
|
||||||
fImageColorSpace, fBudgeted);
|
|
||||||
}
|
|
||||||
|
|
||||||
GrContext* context() const override { return fContext.get(); }
|
|
||||||
GrTextureProxy* peekProxy() const override { return nullptr; }
|
|
||||||
sk_sp<GrTextureProxy> asTextureProxyRef() const override;
|
sk_sp<GrTextureProxy> asTextureProxyRef() const override;
|
||||||
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerState&, SkColorSpace*,
|
|
||||||
sk_sp<SkColorSpace>*,
|
|
||||||
SkScalar scaleAdjust[2]) const override;
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> refPinnedTextureProxy(uint32_t* uniqueID) const override {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
|
||||||
GrSurfaceOrigin* origin) const override {
|
|
||||||
return GrBackendTexture(); // invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
GrTexture* onGetTexture() const override { return nullptr; }
|
|
||||||
|
|
||||||
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
||||||
int srcX, int srcY, CachingHint) const override;
|
int srcX, int srcY, CachingHint) const override;
|
||||||
@ -61,8 +38,6 @@ public:
|
|||||||
sk_sp<SkCachedData> getPlanes(SkYUVSizeInfo*, SkYUVColorSpace*,
|
sk_sp<SkCachedData> getPlanes(SkYUVSizeInfo*, SkYUVColorSpace*,
|
||||||
const void* planes[3]) override { return nullptr; }
|
const void* planes[3]) override { return nullptr; }
|
||||||
|
|
||||||
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override { return nullptr; }
|
|
||||||
|
|
||||||
// These need to match the ones defined elsewhere
|
// These need to match the ones defined elsewhere
|
||||||
typedef ReleaseContext TextureContext;
|
typedef ReleaseContext TextureContext;
|
||||||
typedef void (*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
|
typedef void (*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
|
||||||
@ -128,10 +103,7 @@ public:
|
|||||||
GrSurfaceOrigin imageOrigin,
|
GrSurfaceOrigin imageOrigin,
|
||||||
sk_sp<SkColorSpace> imageColorSpace);
|
sk_sp<SkColorSpace> imageColorSpace);
|
||||||
|
|
||||||
bool onIsValid(GrContext*) const override { return false; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sk_sp<GrContext> fContext;
|
|
||||||
// This array will usually only be sparsely populated.
|
// This array will usually only be sparsely populated.
|
||||||
// The actual non-null fields are dictated by the 'fYUVAIndices' indices
|
// The actual non-null fields are dictated by the 'fYUVAIndices' indices
|
||||||
sk_sp<GrTextureProxy> fProxies[4];
|
sk_sp<GrTextureProxy> fProxies[4];
|
||||||
@ -140,13 +112,10 @@ private:
|
|||||||
// using the separate YUVA planes. From thence forth we will only use the
|
// using the separate YUVA planes. From thence forth we will only use the
|
||||||
// the RGBProxy.
|
// the RGBProxy.
|
||||||
sk_sp<GrTextureProxy> fRGBProxy;
|
sk_sp<GrTextureProxy> fRGBProxy;
|
||||||
const SkBudgeted fBudgeted;
|
const SkYUVColorSpace fYUVColorSpace;
|
||||||
const SkYUVColorSpace fColorSpace;
|
|
||||||
GrSurfaceOrigin fOrigin;
|
GrSurfaceOrigin fOrigin;
|
||||||
SkAlphaType fImageAlphaType;
|
|
||||||
sk_sp<SkColorSpace> fImageColorSpace;
|
|
||||||
|
|
||||||
typedef SkImage_Base INHERITED;
|
typedef SkImage_GpuBase INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user