Move read/write-Pixels up to GrSurfaceContext
This still needs to be propagated out in several ways: replace more instances of GrSurface::read/write-Pixels add colorSpace to more instances of the TextureContext but it establishes a beach-head and is exciting enough as is. Change-Id: If86035aa0245e70b54541e83722b3c75bc5ade13 Reviewed-on: https://skia-review.googlesource.com/7172 Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
dfff166db5
commit
2c86249465
@ -316,34 +316,6 @@ public:
|
||||
*/
|
||||
void prepareForExternalIO();
|
||||
|
||||
/**
|
||||
* Reads a rectangle of pixels from the render target context.
|
||||
* @param dstInfo image info for the destination
|
||||
* @param dstBuffer destination pixels for the read
|
||||
* @param dstRowBytes bytes in a row of 'dstBuffer'
|
||||
* @param x x offset w/in the render target context from which to read
|
||||
* @param y y offset w/in the render target context from which to read
|
||||
*
|
||||
* @return true if the read succeeded, false if not. The read can fail because of an
|
||||
* unsupported pixel config.
|
||||
*/
|
||||
bool readPixels(const SkImageInfo& dstInfo, void* dstBuffer, size_t dstRowBytes, int x, int y);
|
||||
|
||||
/**
|
||||
* Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
|
||||
* renderTargetContext at the specified position.
|
||||
* @param srcInfo image info for the source pixels
|
||||
* @param srcBuffer source for the write
|
||||
* @param srcRowBytes bytes in a row of 'srcBuffer'
|
||||
* @param x x offset w/in the render target context at which to write
|
||||
* @param y y offset w/in the render target context at which to write
|
||||
*
|
||||
* @return true if the write succeeded, false if not. The write can fail because of an
|
||||
* unsupported pixel config.
|
||||
*/
|
||||
bool writePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes,
|
||||
int x, int y);
|
||||
|
||||
bool isStencilBufferMultisampled() const {
|
||||
return fRenderTargetProxy->isStencilBufferMultisampled();
|
||||
}
|
||||
@ -356,10 +328,7 @@ public:
|
||||
int height() const { return fRenderTargetProxy->height(); }
|
||||
GrPixelConfig config() const { return fRenderTargetProxy->config(); }
|
||||
int numColorSamples() const { return fRenderTargetProxy->numColorSamples(); }
|
||||
bool isGammaCorrect() const { return SkToBool(fColorSpace.get()); }
|
||||
const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
|
||||
SkColorSpace* getColorSpace() const { return fColorSpace.get(); }
|
||||
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
|
||||
GrColorSpaceXform* getColorXformFromSRGB() const { return fColorXformFromSRGB.get(); }
|
||||
GrSurfaceOrigin origin() const { return fRenderTargetProxy->origin(); }
|
||||
|
||||
@ -396,7 +365,7 @@ public:
|
||||
|
||||
protected:
|
||||
GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTargetProxy>,
|
||||
sk_sp<SkColorSpace>, const SkSurfaceProps* surfaceProps, GrAuditTrail*,
|
||||
sk_sp<SkColorSpace>, const SkSurfaceProps*, GrAuditTrail*,
|
||||
GrSingleOwner*);
|
||||
|
||||
GrDrawingManager* drawingManager() { return fDrawingManager; }
|
||||
@ -469,6 +438,10 @@ private:
|
||||
const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&);
|
||||
|
||||
bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
|
||||
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) override;
|
||||
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) override;
|
||||
|
||||
// This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
|
||||
void addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>);
|
||||
@ -483,7 +456,6 @@ private:
|
||||
GrRenderTargetOpList* fOpList;
|
||||
GrInstancedPipelineInfo fInstancedPipelineInfo;
|
||||
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
sk_sp<GrColorSpaceXform> fColorXformFromSRGB;
|
||||
SkSurfaceProps fSurfaceProps;
|
||||
|
||||
|
@ -30,6 +30,10 @@ class SK_API GrSurfaceContext : public SkRefCnt {
|
||||
public:
|
||||
~GrSurfaceContext() override {}
|
||||
|
||||
SkColorSpace* getColorSpace() const { return fColorSpace.get(); }
|
||||
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
|
||||
bool isGammaCorrect() const { return SkToBool(fColorSpace.get()); }
|
||||
|
||||
/*
|
||||
* Copy 'src' into the proxy backing this context
|
||||
* @param src src of pixels
|
||||
@ -52,6 +56,39 @@ public:
|
||||
SkIPoint::Make(0, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a rectangle of pixels from the render target context.
|
||||
* @param dstInfo image info for the destination
|
||||
* @param dstBuffer destination pixels for the read
|
||||
* @param dstRowBytes bytes in a row of 'dstBuffer'
|
||||
* @param x x offset w/in the render target context from which to read
|
||||
* @param y y offset w/in the render target context from which to read
|
||||
*
|
||||
* @return true if the read succeeded, false if not. The read can fail because of an
|
||||
* unsupported pixel config.
|
||||
*/
|
||||
bool readPixels(const SkImageInfo& dstInfo, void* dstBuffer, size_t dstRowBytes,
|
||||
int x, int y) {
|
||||
return this->onReadPixels(dstInfo, dstBuffer, dstRowBytes, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
|
||||
* renderTargetContext at the specified position.
|
||||
* @param srcInfo image info for the source pixels
|
||||
* @param srcBuffer source for the write
|
||||
* @param srcRowBytes bytes in a row of 'srcBuffer'
|
||||
* @param x x offset w/in the render target context at which to write
|
||||
* @param y y offset w/in the render target context at which to write
|
||||
*
|
||||
* @return true if the write succeeded, false if not. The write can fail because of an
|
||||
* unsupported pixel config.
|
||||
*/
|
||||
bool writePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes,
|
||||
int x, int y) {
|
||||
return this->onWritePixels(srcInfo, srcBuffer, srcRowBytes, x, y);
|
||||
}
|
||||
|
||||
// TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy?
|
||||
virtual GrSurfaceProxy* asDeferredSurface() = 0;
|
||||
virtual GrTextureProxy* asDeferredTexture() = 0;
|
||||
@ -66,11 +103,12 @@ public:
|
||||
protected:
|
||||
friend class GrSurfaceContextPriv;
|
||||
|
||||
GrSurfaceContext(GrContext*, GrAuditTrail*, GrSingleOwner*);
|
||||
GrSurfaceContext(GrContext*, sk_sp<SkColorSpace>, GrAuditTrail*, GrSingleOwner*);
|
||||
|
||||
SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
|
||||
|
||||
GrContext* fContext;
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
GrAuditTrail* fAuditTrail;
|
||||
|
||||
// In debug builds we guard against improper thread handling
|
||||
@ -80,6 +118,10 @@ private:
|
||||
virtual bool onCopy(GrSurfaceProxy* src,
|
||||
const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) = 0;
|
||||
virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) = 0;
|
||||
virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) = 0;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
@ -32,8 +32,8 @@ public:
|
||||
GrRenderTargetProxy* asDeferredRenderTarget() override;
|
||||
|
||||
protected:
|
||||
GrTextureContext(GrContext*, GrDrawingManager*, sk_sp<GrTextureProxy>, GrAuditTrail*,
|
||||
GrSingleOwner*);
|
||||
GrTextureContext(GrContext*, GrDrawingManager*, sk_sp<GrTextureProxy>,
|
||||
sk_sp<SkColorSpace>, GrAuditTrail*, GrSingleOwner*);
|
||||
|
||||
GrDrawingManager* drawingManager() { return fDrawingManager; }
|
||||
|
||||
@ -43,6 +43,10 @@ private:
|
||||
friend class GrDrawingManager; // for ctor
|
||||
|
||||
bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
|
||||
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) override;
|
||||
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) override;
|
||||
|
||||
GrTextureOpList* getOpList();
|
||||
|
||||
|
@ -593,14 +593,16 @@ sk_sp<GrRenderTargetContext> GrContextPriv::makeWrappedRenderTargetContext(
|
||||
surfaceProps);
|
||||
}
|
||||
|
||||
sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy) {
|
||||
sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
ASSERT_SINGLE_OWNER_PRIV
|
||||
|
||||
if (proxy->asRenderTargetProxy()) {
|
||||
return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr);
|
||||
return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
|
||||
std::move(colorSpace), nullptr);
|
||||
} else {
|
||||
SkASSERT(proxy->asTextureProxy());
|
||||
return this->drawingManager()->makeTextureContext(std::move(proxy));
|
||||
return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
|
||||
}
|
||||
}
|
||||
|
||||
@ -609,7 +611,7 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface
|
||||
|
||||
sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
|
||||
|
||||
return this->makeWrappedSurfaceContext(std::move(proxy));
|
||||
return this->makeWrappedSurfaceContext(std::move(proxy), nullptr);
|
||||
}
|
||||
|
||||
sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
|
||||
@ -619,7 +621,7 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfac
|
||||
sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc,
|
||||
fit, isDstBudgeted);
|
||||
|
||||
return this->makeWrappedSurfaceContext(std::move(proxy));
|
||||
return this->makeWrappedSurfaceContext(std::move(proxy), nullptr);
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
|
||||
|
@ -28,7 +28,8 @@ public:
|
||||
// Create a surfaceContext that wraps an existing texture or renderTarget
|
||||
sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex);
|
||||
|
||||
sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy);
|
||||
sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
|
||||
sk_sp<SkColorSpace>);
|
||||
|
||||
sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
|
||||
SkBackingFit dstFit,
|
||||
|
@ -238,16 +238,16 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
|
||||
|
||||
// SkSurface catches bad color space usage at creation. This check handles anything that slips
|
||||
// by, including internal usage. We allow a null color space here, for read/write pixels and
|
||||
// other special code paths. If a color space is provided, though, enforce all other rules.
|
||||
if (colorSpace && !SkSurface_Gpu::Valid(fContext, rtp->config(), colorSpace.get())) {
|
||||
if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
|
||||
SkDEBUGFAIL("Invalid config and colorspace combination");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
|
||||
|
||||
bool useDIF = false;
|
||||
if (surfaceProps) {
|
||||
useDIF = surfaceProps->isUseDeviceIndependentFonts();
|
||||
@ -276,16 +276,27 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
|
||||
fSingleOwner));
|
||||
}
|
||||
|
||||
sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy) {
|
||||
sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// SkSurface catches bad color space usage at creation. This check handles anything that slips
|
||||
// by, including internal usage. We allow a null color space here, for read/write pixels and
|
||||
// other special code paths. If a color space is provided, though, enforce all other rules.
|
||||
if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
|
||||
SkDEBUGFAIL("Invalid config and colorspace combination");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// GrTextureRenderTargets should always be using GrRenderTargetContext
|
||||
SkASSERT(!sProxy->asRenderTargetProxy());
|
||||
|
||||
sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
|
||||
|
||||
return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
|
||||
fContext->getAuditTrail(), fSingleOwner));
|
||||
std::move(colorSpace),
|
||||
fContext->getAuditTrail(),
|
||||
fSingleOwner));
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
|
||||
sk_sp<SkColorSpace>,
|
||||
const SkSurfaceProps*);
|
||||
sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>);
|
||||
sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>);
|
||||
|
||||
// The caller automatically gets a ref on the returned opList. It must
|
||||
// be balanced by an unref call.
|
||||
|
@ -81,15 +81,13 @@ GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
GrAuditTrail* auditTrail,
|
||||
GrSingleOwner* singleOwner)
|
||||
: GrSurfaceContext(context, auditTrail, singleOwner)
|
||||
: GrSurfaceContext(context, std::move(colorSpace), auditTrail, singleOwner)
|
||||
, fDrawingManager(drawingMgr)
|
||||
, fRenderTargetProxy(std::move(rtp))
|
||||
, fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
|
||||
, fInstancedPipelineInfo(fRenderTargetProxy.get())
|
||||
, fColorSpace(std::move(colorSpace))
|
||||
, fColorXformFromSRGB(nullptr)
|
||||
, fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
|
||||
{
|
||||
, fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps)) {
|
||||
if (fColorSpace) {
|
||||
// sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation
|
||||
auto srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
|
||||
@ -158,6 +156,56 @@ bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy,
|
||||
return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint);
|
||||
}
|
||||
|
||||
// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
|
||||
bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) {
|
||||
// TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrRenderTarget> rt(
|
||||
sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
|
||||
if (!rt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rt->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
|
||||
config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
|
||||
}
|
||||
|
||||
// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
|
||||
bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) {
|
||||
// TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrRenderTarget> rt(
|
||||
sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
|
||||
if (!rt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rt->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
|
||||
config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
|
||||
}
|
||||
|
||||
|
||||
void GrRenderTargetContext::drawText(const GrClip& clip, const SkPaint& skPaint,
|
||||
const SkMatrix& viewMatrix, const char text[],
|
||||
size_t byteLength, SkScalar x, SkScalar y,
|
||||
@ -1267,53 +1315,6 @@ void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
|
||||
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
|
||||
}
|
||||
|
||||
bool GrRenderTargetContext::readPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) {
|
||||
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrRenderTarget> rt(
|
||||
sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
|
||||
if (!rt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rt->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
|
||||
config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
|
||||
}
|
||||
|
||||
bool GrRenderTargetContext::writePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) {
|
||||
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrRenderTarget> rt(
|
||||
sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
|
||||
if (!rt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rt->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
|
||||
config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
|
||||
}
|
||||
|
||||
// Can 'path' be drawn as a pair of filled nested rectangles?
|
||||
static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
|
||||
|
||||
|
@ -15,9 +15,11 @@
|
||||
// stack. When this occurs with a closed GrOpList, a new one will be allocated
|
||||
// when the renderTargetContext attempts to use it (via getOpList).
|
||||
GrSurfaceContext::GrSurfaceContext(GrContext* context,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
GrAuditTrail* auditTrail,
|
||||
GrSingleOwner* singleOwner)
|
||||
: fContext(context)
|
||||
, fColorSpace(std::move(colorSpace))
|
||||
, fAuditTrail(auditTrail)
|
||||
#ifdef SK_DEBUG
|
||||
, fSingleOwner(singleOwner)
|
||||
|
@ -19,9 +19,10 @@
|
||||
GrTextureContext::GrTextureContext(GrContext* context,
|
||||
GrDrawingManager* drawingMgr,
|
||||
sk_sp<GrTextureProxy> textureProxy,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
GrAuditTrail* auditTrail,
|
||||
GrSingleOwner* singleOwner)
|
||||
: GrSurfaceContext(context, auditTrail, singleOwner)
|
||||
: GrSurfaceContext(context, std::move(colorSpace), auditTrail, singleOwner)
|
||||
, fDrawingManager(drawingMgr)
|
||||
, fTextureProxy(std::move(textureProxy))
|
||||
, fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) {
|
||||
@ -75,11 +76,11 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_MDB
|
||||
// We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
|
||||
// execute the copy immediately. Ensure the data is ready.
|
||||
src->flushWrites();
|
||||
|
||||
#ifndef ENABLE_MDB
|
||||
// We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
|
||||
// execute the copy immediately. Ensure the data is ready.
|
||||
src->flushWrites();
|
||||
#endif
|
||||
|
||||
// TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
|
||||
@ -100,3 +101,50 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
|
||||
bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
|
||||
size_t dstRowBytes, int x, int y) {
|
||||
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider())));
|
||||
if (!tex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tex->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
|
||||
config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
|
||||
}
|
||||
|
||||
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
|
||||
bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
|
||||
size_t srcRowBytes, int x, int y) {
|
||||
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
|
||||
// Deferral of the VRAM resources must end in this instance anyway
|
||||
sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider())));
|
||||
if (!tex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tex->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
|
||||
config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
|
||||
}
|
||||
|
@ -125,7 +125,8 @@ static bool save_pixels(GrContext* context, GrSurfaceProxy* sProxy, const char*
|
||||
}
|
||||
|
||||
sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
|
||||
sk_ref_sp(sProxy)));
|
||||
sk_ref_sp(sProxy),
|
||||
nullptr));
|
||||
if (!sContext || !sContext->asDeferredTexture()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -91,6 +91,10 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace,
|
||||
return true;
|
||||
}
|
||||
|
||||
sk_sp<GrSurfaceProxy> SkImage_Gpu::refProxy() const {
|
||||
return GrSurfaceProxy::MakeWrapped(fTexture);
|
||||
}
|
||||
|
||||
GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
|
||||
SkColorSpace* dstColorSpace,
|
||||
sk_sp<SkColorSpace>* texColorSpace) const {
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
sk_sp<SkColorSpace>*) const override;
|
||||
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
|
||||
|
||||
sk_sp<GrSurfaceProxy> refProxy() const;
|
||||
GrTexture* peekTexture() const override { return fTexture.get(); }
|
||||
sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const override {
|
||||
*uniqueID = this->uniqueID();
|
||||
@ -51,6 +52,9 @@ public:
|
||||
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
||||
int srcX, int srcY, CachingHint) const override;
|
||||
|
||||
GrContext* context() { return fTexture->getContext(); }
|
||||
sk_sp<SkColorSpace> refColorSpace() { return fColorSpace; }
|
||||
|
||||
private:
|
||||
sk_sp<GrTexture> fTexture;
|
||||
const SkAlphaType fAlphaType;
|
||||
|
@ -91,7 +91,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
|
||||
}
|
||||
|
||||
sk_sp<GrSurfaceContext> sContext =
|
||||
context->contextPriv().makeWrappedSurfaceContext(dst);
|
||||
context->contextPriv().makeWrappedSurfaceContext(dst, nullptr);
|
||||
|
||||
bool result = sContext->copy(src.get(), srcRect, dstPoint);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
#include "GrContextPriv.h"
|
||||
#include "GrRenderTargetContext.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrResourceProvider.h"
|
||||
@ -626,7 +627,7 @@ static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target(
|
||||
}
|
||||
|
||||
static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface,
|
||||
std::function<GrSurface*(SkSurface*)> grSurfaceGetter,
|
||||
std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceGetter,
|
||||
uint32_t expectedValue) {
|
||||
if (!surface) {
|
||||
ERRORF(reporter, "Could not create GPU SkSurface.");
|
||||
@ -637,13 +638,15 @@ static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> su
|
||||
std::unique_ptr<uint32_t[]> pixels(new uint32_t[w * h]);
|
||||
sk_memset32(pixels.get(), ~expectedValue, w * h);
|
||||
|
||||
sk_sp<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get())));
|
||||
if (!grSurface) {
|
||||
sk_sp<GrSurfaceContext> grSurfaceContext(grSurfaceGetter(surface.get()));
|
||||
if (!grSurfaceContext) {
|
||||
ERRORF(reporter, "Could access render target of GPU SkSurface.");
|
||||
return;
|
||||
}
|
||||
surface.reset();
|
||||
grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get());
|
||||
|
||||
SkImageInfo ii = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
grSurfaceContext->readPixels(ii, pixels.get(), 0, 0, 0);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
uint32_t pixel = pixels.get()[y * w + x];
|
||||
@ -666,16 +669,21 @@ static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> su
|
||||
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) {
|
||||
GrContext* context = ctxInfo.grContext();
|
||||
|
||||
std::function<GrSurface*(SkSurface*)> grSurfaceGetters[] = {
|
||||
std::function<sk_sp<GrSurfaceContext>(SkSurface*)> grSurfaceContextGetters[] = {
|
||||
[] (SkSurface* s){
|
||||
GrRenderTargetContext* rtc =
|
||||
s->getCanvas()->internal_private_accessTopLayerRenderTargetContext();
|
||||
return rtc->accessRenderTarget(); },
|
||||
[] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot());
|
||||
return as_IB(i)->peekTexture(); }
|
||||
return sk_ref_sp(s->getCanvas()->internal_private_accessTopLayerRenderTargetContext());
|
||||
},
|
||||
[] (SkSurface* s){
|
||||
sk_sp<SkImage> i(s->makeImageSnapshot());
|
||||
SkImage_Gpu* gpuImage = (SkImage_Gpu *) as_IB(i);
|
||||
sk_sp<GrSurfaceProxy> proxy = gpuImage->refProxy();
|
||||
GrContext* context = gpuImage->context();
|
||||
return context->contextPriv().makeWrappedSurfaceContext(std::move(proxy),
|
||||
gpuImage->refColorSpace());
|
||||
}
|
||||
};
|
||||
|
||||
for (auto grSurfaceGetter : grSurfaceGetters) {
|
||||
for (auto grSurfaceGetter : grSurfaceContextGetters) {
|
||||
// Test that non-wrapped RTs are created clear.
|
||||
for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surface}) {
|
||||
auto surface = surface_func(context, kPremul_SkAlphaType, nullptr);
|
||||
|
Loading…
Reference in New Issue
Block a user