Reland "Write pixels goes through GrRenderTask system."
This reverts commit1eea1ea8c1
. Reason for revert: fixed implicit copy cons Original change's description: > Revert "Write pixels goes through GrRenderTask system." > > This reverts commit27efe6cb1e
. > > Reason for revert: wasm compile > > Original change's description: > > Write pixels goes through GrRenderTask system. > > > > The specific motivation is to remove some uses of GrResourceProvider > > making textures with data in lazy callbacks. But it's a general > > improvement that could allow use cases like writePixels in DDL > > recordings. > > > > Bug: skia:11204 > > > > Change-Id: Ic55c3f75976a1d3a7d93981e21be75a3053ef069 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/356845 > > Reviewed-by: Adlai Holler <adlai@google.com> > > Commit-Queue: Brian Salomon <bsalomon@google.com> > > TBR=bsalomon@google.com,adlai@google.com > > Change-Id: I116caf1e4dd9015270b9d4f810bd26e0e30a6497 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia:11204 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/359559 > Reviewed-by: Brian Salomon <bsalomon@google.com> > Commit-Queue: Brian Salomon <bsalomon@google.com> TBR=bsalomon@google.com,adlai@google.com # Not skipping CQ checks because this is a reland. Bug: skia:11204 Change-Id: I7d8f92415995f03301ffb147500d972e6bd17640 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/359561 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
70a0d2cc4f
commit
be1084b5d9
@ -276,6 +276,8 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrWaitRenderTask.h",
|
||||
"$_src/gpu/GrWindowRectangles.h",
|
||||
"$_src/gpu/GrWindowRectsState.h",
|
||||
"$_src/gpu/GrWritePixelsRenderTask.cpp",
|
||||
"$_src/gpu/GrWritePixelsRenderTask.h",
|
||||
"$_src/gpu/GrXferProcessor.cpp",
|
||||
"$_src/gpu/GrXferProcessor.h",
|
||||
"$_src/gpu/GrYUVABackendTextures.cpp",
|
||||
|
@ -185,8 +185,7 @@ bool GrDirectContext::init() {
|
||||
SkASSERT(this->threadSafeCache());
|
||||
|
||||
fStrikeCache = std::make_unique<GrStrikeCache>();
|
||||
fResourceCache = std::make_unique<GrResourceCache>(this->caps(), this->singleOwner(),
|
||||
this->contextID());
|
||||
fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(), this->contextID());
|
||||
fResourceCache->setProxyProvider(this->proxyProvider());
|
||||
fResourceCache->setThreadSafeCache(this->threadSafeCache());
|
||||
fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "src/gpu/GrTracing.h"
|
||||
#include "src/gpu/GrTransferFromRenderTask.h"
|
||||
#include "src/gpu/GrWaitRenderTask.h"
|
||||
#include "src/gpu/GrWritePixelsRenderTask.h"
|
||||
#include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h"
|
||||
#include "src/gpu/text/GrSDFTOptions.h"
|
||||
#include "src/image/SkSurface_Gpu.h"
|
||||
@ -859,6 +860,49 @@ bool GrDrawingManager::newCopyRenderTask(sk_sp<GrSurfaceProxy> src,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrDrawingManager::newWritePixelsTask(sk_sp<GrSurfaceProxy> dst,
|
||||
SkIRect rect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel levels[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> owner) {
|
||||
SkDEBUGCODE(this->validate());
|
||||
SkASSERT(fContext);
|
||||
|
||||
this->closeActiveOpsTask();
|
||||
const GrCaps& caps = *fContext->priv().caps();
|
||||
|
||||
// On platforms that prefer flushes over VRAM use (i.e., ANGLE) we're better off forcing a
|
||||
// complete flush here.
|
||||
if (!caps.preferVRAMUseOverFlushes()) {
|
||||
this->flushSurfaces(SkSpan<GrSurfaceProxy*>{},
|
||||
SkSurface::BackendSurfaceAccess::kNoAccess,
|
||||
GrFlushInfo{},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
GrRenderTask* task = this->appendTask(GrWritePixelsTask::Make(this,
|
||||
std::move(dst),
|
||||
rect,
|
||||
srcColorType,
|
||||
dstColorType,
|
||||
levels,
|
||||
levelCount,
|
||||
std::move(owner)));
|
||||
if (!task) {
|
||||
return false;
|
||||
}
|
||||
|
||||
task->makeClosed(caps);
|
||||
|
||||
// We have closed the previous active oplist but since a new oplist isn't being added there
|
||||
// shouldn't be an active one.
|
||||
SkASSERT(!fActiveOpsTask);
|
||||
SkDEBUGCODE(this->validate());
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method finds a path renderer that can draw the specified path on
|
||||
* the provided target.
|
||||
|
@ -83,6 +83,18 @@ public:
|
||||
SkIPoint dstPoint,
|
||||
GrSurfaceOrigin);
|
||||
|
||||
// Adds a task that writes the data from the passed GrMipLevels to dst. The lifetime of the
|
||||
// pixel data in the levels should be tied to the passed SkData. srcColorType is the color
|
||||
// type of the GrMipLevels. dstColorType is the color type being used with dst and must
|
||||
// be compatible with dst's format according to GrCaps::areColorTypeAndFormatCompatible().
|
||||
bool newWritePixelsTask(sk_sp<GrSurfaceProxy> dst,
|
||||
SkIRect rect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> storage);
|
||||
|
||||
GrRecordingContext* getContext() { return fContext; }
|
||||
|
||||
GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef GrPixmap_DEFINED
|
||||
#define GrPixmap_DEFINED
|
||||
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkPixmap.h"
|
||||
#include "src/gpu/GrImageInfo.h"
|
||||
|
||||
@ -28,6 +29,18 @@ public:
|
||||
/* implicit */ GrPixmap(const SkPixmap& pixmap)
|
||||
: GrPixmap(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {}
|
||||
|
||||
/**
|
||||
* Returns a GrPixmap that owns its backing store. Copies of the pixmap will share ownership.
|
||||
*/
|
||||
static GrPixmap Allocate(const GrImageInfo& info) {
|
||||
size_t rb = info.minRowBytes();
|
||||
size_t size = info.height()*rb;
|
||||
if (!size) {
|
||||
return {};
|
||||
}
|
||||
return GrPixmap(info, SkData::MakeUninitialized(size), rb);
|
||||
}
|
||||
|
||||
const GrImageInfo& info() const { return fInfo; }
|
||||
const GrColorInfo& colorInfo() const { return fInfo.colorInfo(); }
|
||||
|
||||
@ -35,6 +48,8 @@ public:
|
||||
size_t rowBytes() const { return fRowBytes; }
|
||||
|
||||
bool hasPixels() const { return SkToBool(fAddr); }
|
||||
bool ownsPixels() const { return SkToBool(fPixelStorage); }
|
||||
sk_sp<SkData> pixelStorage() const { return fPixelStorage; }
|
||||
|
||||
int width() const { return fInfo.width(); }
|
||||
int height() const { return fInfo.height(); }
|
||||
@ -62,21 +77,16 @@ public:
|
||||
return {this->info().makeDimensions(rect.size()), addr, fRowBytes};
|
||||
}
|
||||
|
||||
/** Returns a GrPixmap and a unique_ptr that owns the storage backing the pixmap. */
|
||||
static std::tuple<GrPixmap, std::unique_ptr<char[]>> Allocate(const GrImageInfo& info) {
|
||||
size_t rb = info.minRowBytes();
|
||||
size_t size = info.height()*rb;
|
||||
if (!size) {
|
||||
return {};
|
||||
}
|
||||
std::unique_ptr<char[]> storage(new char[size]);
|
||||
return {GrPixmap(info, storage.get(), rb), std::move(storage)};
|
||||
private:
|
||||
GrPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
|
||||
: GrPixmap(std::move(info), storage->writable_data(), rowBytes) {
|
||||
fPixelStorage = std::move(storage);
|
||||
}
|
||||
|
||||
private:
|
||||
void* fAddr = nullptr;
|
||||
size_t fRowBytes = 0;
|
||||
GrImageInfo fInfo;
|
||||
sk_sp<SkData> fPixelStorage;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -108,13 +108,11 @@ inline bool GrResourceCache::TextureAwaitingUnref::finished() { return !fNumUnre
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrResourceCache::GrResourceCache(const GrCaps* caps, GrSingleOwner* singleOwner,
|
||||
uint32_t contextUniqueID)
|
||||
GrResourceCache::GrResourceCache(GrSingleOwner* singleOwner, uint32_t contextUniqueID)
|
||||
: fInvalidUniqueKeyInbox(contextUniqueID)
|
||||
, fFreedTextureInbox(contextUniqueID)
|
||||
, fContextUniqueID(contextUniqueID)
|
||||
, fSingleOwner(singleOwner)
|
||||
, fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) {
|
||||
, fSingleOwner(singleOwner) {
|
||||
SkASSERT(contextUniqueID != SK_InvalidUniqueID);
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ static inline bool SkShouldPostMessageToBus(
|
||||
*/
|
||||
class GrResourceCache {
|
||||
public:
|
||||
GrResourceCache(const GrCaps*, GrSingleOwner* owner, uint32_t contextUniqueID);
|
||||
GrResourceCache(GrSingleOwner* owner, uint32_t contextUniqueID);
|
||||
~GrResourceCache();
|
||||
|
||||
// Default maximum number of bytes of gpu memory of budgeted resources in the cache.
|
||||
@ -371,8 +371,6 @@ private:
|
||||
// This resource is allowed to be in the nonpurgeable array for the sake of validate() because
|
||||
// we're in the midst of converting it to purgeable status.
|
||||
SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation = nullptr;)
|
||||
|
||||
bool fPreferVRAMUseOverFlushes = false;
|
||||
};
|
||||
|
||||
class GrResourceCache::ResourceAccess {
|
||||
|
@ -494,15 +494,12 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, GrPixmap src, SkIP
|
||||
bool convert = premul || unpremul || needColorConversion || makeTight ||
|
||||
(src.colorType() != allowedColorType) || flip;
|
||||
|
||||
std::unique_ptr<char[]> tmpPixels;
|
||||
if (convert) {
|
||||
if (convert || !src.ownsPixels()) {
|
||||
GrImageInfo tmpInfo(allowedColorType,
|
||||
this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace(),
|
||||
src.dimensions());
|
||||
auto tmpRB = tmpInfo.minRowBytes();
|
||||
tmpPixels.reset(new char[tmpRB * tmpInfo.height()]);
|
||||
GrPixmap tmp(tmpInfo, tmpPixels.get(), tmpRB);
|
||||
GrPixmap tmp = GrPixmap::Allocate(tmpInfo);
|
||||
|
||||
SkAssertResult(GrConvertPixels(tmp, src, flip));
|
||||
|
||||
@ -510,16 +507,17 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, GrPixmap src, SkIP
|
||||
pt.fY = flip ? dstSurface->height() - pt.fY - tmpInfo.height() : pt.fY;
|
||||
}
|
||||
|
||||
// On platforms that prefer flushes over VRAM use (i.e., ANGLE) we're better off forcing a
|
||||
// complete flush here. On platforms that prefer VRAM use over flushes we're better off
|
||||
// giving the drawing manager the chance of skipping the flush (i.e., by passing in the
|
||||
// destination proxy)
|
||||
// TODO: should this policy decision just be moved into the drawing manager?
|
||||
dContext->priv().flushSurface(caps->preferVRAMUseOverFlushes() ? dstProxy : nullptr);
|
||||
|
||||
return dContext->priv().getGpu()->writePixels(dstSurface, pt.fX, pt.fY, src.width(),
|
||||
src.height(), this->colorInfo().colorType(),
|
||||
src.colorType(), src.addr(), src.rowBytes());
|
||||
GrMipLevel level;
|
||||
level.fPixels = src.addr();
|
||||
level.fRowBytes = src.rowBytes();
|
||||
return dContext->priv().drawingManager()->newWritePixelsTask(
|
||||
this->asSurfaceProxyRef(),
|
||||
SkIRect::MakePtSize(pt, src.dimensions()),
|
||||
src.colorType(),
|
||||
dstColorType,
|
||||
&level,
|
||||
1,
|
||||
src.pixelStorage());
|
||||
}
|
||||
|
||||
void GrSurfaceContext::asyncRescaleAndReadPixels(GrDirectContext* dContext,
|
||||
@ -634,18 +632,13 @@ public:
|
||||
AsyncReadResult(uint32_t inboxID) : fInboxID(inboxID) {}
|
||||
~AsyncReadResult() override {
|
||||
for (int i = 0; i < fPlanes.count(); ++i) {
|
||||
if (!fPlanes[i].fMappedBuffer) {
|
||||
delete[] static_cast<const char*>(fPlanes[i].fData);
|
||||
} else {
|
||||
GrClientMappedBufferManager::BufferFinishedMessageBus::Post(
|
||||
{std::move(fPlanes[i].fMappedBuffer), fInboxID});
|
||||
}
|
||||
fPlanes[i].releaseMappedBuffer(fInboxID);
|
||||
}
|
||||
}
|
||||
|
||||
int count() const override { return fPlanes.count(); }
|
||||
const void* data(int i) const override { return fPlanes[i].fData; }
|
||||
size_t rowBytes(int i) const override { return fPlanes[i].fRowBytes; }
|
||||
const void* data(int i) const override { return fPlanes[i].data(); }
|
||||
size_t rowBytes(int i) const override { return fPlanes[i].rowBytes(); }
|
||||
|
||||
bool addTransferResult(const PixelTransferResult& result,
|
||||
SkISize dimensions,
|
||||
@ -657,9 +650,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
if (result.fPixelConverter) {
|
||||
std::unique_ptr<char[]> convertedData(new char[rowBytes * dimensions.height()]);
|
||||
result.fPixelConverter(convertedData.get(), mappedData);
|
||||
this->addCpuPlane(std::move(convertedData), rowBytes);
|
||||
size_t size = rowBytes*dimensions.height();
|
||||
sk_sp<SkData> data = SkData::MakeUninitialized(size);
|
||||
result.fPixelConverter(data->writable_data(), mappedData);
|
||||
this->addCpuPlane(std::move(data), rowBytes);
|
||||
result.fTransferBuffer->unmap();
|
||||
} else {
|
||||
manager->insert(result.fTransferBuffer);
|
||||
@ -668,10 +662,10 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void addCpuPlane(std::unique_ptr<const char[]> data, size_t rowBytes) {
|
||||
void addCpuPlane(sk_sp<SkData> data, size_t rowBytes) {
|
||||
SkASSERT(data);
|
||||
SkASSERT(rowBytes > 0);
|
||||
fPlanes.emplace_back(data.release(), rowBytes, nullptr);
|
||||
fPlanes.emplace_back(std::move(data), rowBytes);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -680,16 +674,46 @@ private:
|
||||
SkASSERT(rowBytes > 0);
|
||||
SkASSERT(mappedBuffer);
|
||||
SkASSERT(mappedBuffer->isMapped());
|
||||
fPlanes.emplace_back(data, rowBytes, std::move(mappedBuffer));
|
||||
fPlanes.emplace_back(std::move(mappedBuffer), rowBytes);
|
||||
}
|
||||
|
||||
struct Plane {
|
||||
Plane(const void* data, size_t rowBytes, sk_sp<GrGpuBuffer> buffer)
|
||||
: fData(data), fRowBytes(rowBytes), fMappedBuffer(std::move(buffer)) {}
|
||||
const void* fData;
|
||||
size_t fRowBytes;
|
||||
// If this is null then fData is heap alloc and must be delete[]ed as const char[].
|
||||
class Plane {
|
||||
public:
|
||||
Plane(sk_sp<GrGpuBuffer> buffer, size_t rowBytes)
|
||||
: fMappedBuffer(std::move(buffer)), fRowBytes(rowBytes) {}
|
||||
Plane(sk_sp<SkData> data, size_t rowBytes) : fData(std::move(data)), fRowBytes(rowBytes) {}
|
||||
|
||||
Plane(const Plane&) = delete;
|
||||
Plane(Plane&&) = default;
|
||||
|
||||
~Plane() { SkASSERT(!fMappedBuffer); }
|
||||
|
||||
Plane& operator=(const Plane&) = delete;
|
||||
Plane& operator=(Plane&&) = default;
|
||||
|
||||
void releaseMappedBuffer(uint32_t inboxID) {
|
||||
if (fMappedBuffer) {
|
||||
GrClientMappedBufferManager::BufferFinishedMessageBus::Post(
|
||||
{std::move(fMappedBuffer), inboxID});
|
||||
}
|
||||
}
|
||||
|
||||
const void* data() const {
|
||||
if (fMappedBuffer) {
|
||||
SkASSERT(!fData);
|
||||
SkASSERT(fMappedBuffer->isMapped());
|
||||
return fMappedBuffer->map();
|
||||
}
|
||||
SkASSERT(fData);
|
||||
return fData->data();
|
||||
}
|
||||
|
||||
size_t rowBytes() const { return fRowBytes; }
|
||||
|
||||
private:
|
||||
sk_sp<SkData> fData;
|
||||
sk_sp<GrGpuBuffer> fMappedBuffer;
|
||||
size_t fRowBytes;
|
||||
};
|
||||
SkSTArray<3, Plane> fPlanes;
|
||||
uint32_t fInboxID;
|
||||
@ -716,9 +740,8 @@ void GrSurfaceContext::asyncReadPixels(GrDirectContext* dContext,
|
||||
auto ii = SkImageInfo::Make(rect.size(), colorType, this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace());
|
||||
auto result = std::make_unique<AsyncReadResult>(0);
|
||||
std::unique_ptr<char[]> data(new char[ii.computeMinByteSize()]);
|
||||
SkPixmap pm(ii, data.get(), ii.minRowBytes());
|
||||
result->addCpuPlane(std::move(data), pm.rowBytes());
|
||||
GrPixmap pm = GrPixmap::Allocate(ii);
|
||||
result->addCpuPlane(pm.pixelStorage(), pm.rowBytes());
|
||||
|
||||
SkIPoint pt{rect.fLeft, rect.fTop};
|
||||
if (!this->readPixels(dContext, pm, pt)) {
|
||||
@ -957,9 +980,9 @@ void GrSurfaceContext::asyncRescaleAndReadPixelsYUV420(GrDirectContext* dContext
|
||||
}
|
||||
|
||||
if (doSynchronousRead) {
|
||||
auto [yPmp, yStorage] = GrPixmap::Allocate(yInfo);
|
||||
auto [uPmp, uStorage] = GrPixmap::Allocate(uvInfo);
|
||||
auto [vPmp, vStorage] = GrPixmap::Allocate(uvInfo);
|
||||
GrPixmap yPmp = GrPixmap::Allocate(yInfo);
|
||||
GrPixmap uPmp = GrPixmap::Allocate(uvInfo);
|
||||
GrPixmap vPmp = GrPixmap::Allocate(uvInfo);
|
||||
if (!yFC->readPixels(dContext, yPmp, {0, 0}) ||
|
||||
!uFC->readPixels(dContext, uPmp, {0, 0}) ||
|
||||
!vFC->readPixels(dContext, vPmp, {0, 0})) {
|
||||
@ -967,9 +990,9 @@ void GrSurfaceContext::asyncRescaleAndReadPixelsYUV420(GrDirectContext* dContext
|
||||
return;
|
||||
}
|
||||
auto result = std::make_unique<AsyncReadResult>(dContext->priv().contextID());
|
||||
result->addCpuPlane(std::move(yStorage), yPmp.rowBytes());
|
||||
result->addCpuPlane(std::move(uStorage), uPmp.rowBytes());
|
||||
result->addCpuPlane(std::move(vStorage), vPmp.rowBytes());
|
||||
result->addCpuPlane(yPmp.pixelStorage(), yPmp.rowBytes());
|
||||
result->addCpuPlane(uPmp.pixelStorage(), uPmp.rowBytes());
|
||||
result->addCpuPlane(vPmp.pixelStorage(), vPmp.rowBytes());
|
||||
callback(callbackContext, std::move(result));
|
||||
return;
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ GrTexture::GrTexture(GrGpu* gpu,
|
||||
} else {
|
||||
fMaxMipmapLevel = SkMipmap::ComputeLevelCount(this->width(), this->height());
|
||||
}
|
||||
if (textureType == GrTextureType::kExternal) {
|
||||
this->setReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
bool GrTexture::StealBackendTexture(sk_sp<GrTexture> texture,
|
||||
|
@ -34,6 +34,9 @@ GrTextureProxy::GrTextureProxy(const GrBackendFormat& format,
|
||||
, fProxyProvider(nullptr)
|
||||
, fDeferredUploader(nullptr) {
|
||||
SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
|
||||
if (this->textureType() == GrTextureType::kExternal) {
|
||||
fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
// Lazy-callback version
|
||||
@ -57,6 +60,9 @@ GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
|
||||
, fProxyProvider(nullptr)
|
||||
, fDeferredUploader(nullptr) {
|
||||
SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
|
||||
if (this->textureType() == GrTextureType::kExternal) {
|
||||
fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapped version
|
||||
@ -74,6 +80,9 @@ GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf,
|
||||
fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider();
|
||||
fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget.get());
|
||||
}
|
||||
if (this->textureType() == GrTextureType::kExternal) {
|
||||
fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
GrTextureProxy::~GrTextureProxy() {
|
||||
|
78
src/gpu/GrWritePixelsRenderTask.cpp
Normal file
78
src/gpu/GrWritePixelsRenderTask.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/gpu/GrWritePixelsRenderTask.h"
|
||||
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrResourceAllocator.h"
|
||||
//
|
||||
|
||||
sk_sp<GrRenderTask> GrWritePixelsTask::Make(GrDrawingManager* dm,
|
||||
sk_sp<GrSurfaceProxy> dst,
|
||||
SkIRect rect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel texels[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> pixelStorage) {
|
||||
return sk_sp<GrRenderTask>(new GrWritePixelsTask(dm,
|
||||
std::move(dst),
|
||||
rect,
|
||||
srcColorType,
|
||||
dstColorType,
|
||||
texels,
|
||||
levelCount,
|
||||
std::move(pixelStorage)));
|
||||
}
|
||||
|
||||
GrWritePixelsTask::GrWritePixelsTask(GrDrawingManager* dm,
|
||||
sk_sp<GrSurfaceProxy> dst,
|
||||
SkIRect rect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel texels[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> pixelStorage)
|
||||
: fRect(rect)
|
||||
, fSrcColorType(srcColorType)
|
||||
, fDstColorType(dstColorType)
|
||||
, fStorage(std::move(pixelStorage)) {
|
||||
SkASSERT(fStorage);
|
||||
this->addTarget(dm, std::move(dst));
|
||||
fLevels.reset(levelCount);
|
||||
std::copy_n(texels, levelCount, fLevels.get());
|
||||
}
|
||||
|
||||
void GrWritePixelsTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
|
||||
alloc->addInterval(this->target(0), alloc->curOp(), alloc->curOp(),
|
||||
GrResourceAllocator::ActualUse::kYes);
|
||||
alloc->incOps();
|
||||
}
|
||||
|
||||
GrRenderTask::ExpectedOutcome GrWritePixelsTask::onMakeClosed(const GrCaps&,
|
||||
SkIRect* targetUpdateBounds) {
|
||||
*targetUpdateBounds = fRect;
|
||||
return ExpectedOutcome::kTargetDirty;
|
||||
}
|
||||
|
||||
bool GrWritePixelsTask::onExecute(GrOpFlushState* flushState) {
|
||||
GrSurfaceProxy* dstProxy = this->target(0);
|
||||
if (!dstProxy->isInstantiated()) {
|
||||
return false;
|
||||
}
|
||||
GrSurface* dstSurface = dstProxy->peekSurface();
|
||||
return flushState->gpu()->writePixels(dstSurface,
|
||||
fRect.fLeft,
|
||||
fRect.fTop,
|
||||
fRect.width(),
|
||||
fRect.height(),
|
||||
fDstColorType,
|
||||
fSrcColorType,
|
||||
fLevels.get(),
|
||||
fLevels.count());
|
||||
}
|
56
src/gpu/GrWritePixelsRenderTask.h
Normal file
56
src/gpu/GrWritePixelsRenderTask.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrWritePixelsTask_DEFINED
|
||||
#define GrWritePixelsTask_DEFINED
|
||||
|
||||
#include "src/gpu/GrRenderTask.h"
|
||||
|
||||
class GrWritePixelsTask final : public GrRenderTask {
|
||||
public:
|
||||
static sk_sp<GrRenderTask> Make(GrDrawingManager*,
|
||||
sk_sp<GrSurfaceProxy>,
|
||||
SkIRect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> pixelStorage);
|
||||
|
||||
private:
|
||||
GrWritePixelsTask(GrDrawingManager*,
|
||||
sk_sp<GrSurfaceProxy> dst,
|
||||
SkIRect,
|
||||
GrColorType srcColorType,
|
||||
GrColorType dstColorType,
|
||||
const GrMipLevel[],
|
||||
int levelCount,
|
||||
sk_sp<SkData> pixelStorage);
|
||||
|
||||
bool onIsUsed(GrSurfaceProxy* proxy) const override { return false; }
|
||||
// If instantiation failed, at flush time we simply will skip doing the write.
|
||||
void handleInternalAllocationFailure() override {}
|
||||
void gatherProxyIntervals(GrResourceAllocator*) const override;
|
||||
ExpectedOutcome onMakeClosed(const GrCaps&, SkIRect* targetUpdateBounds) override;
|
||||
bool onExecute(GrOpFlushState*) override;
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
const char* name() const final { return "WritePixels"; }
|
||||
#endif
|
||||
#ifdef SK_DEBUG
|
||||
void visitProxies_debugOnly(const GrOp::VisitProxyFunc& fn) const override {}
|
||||
#endif
|
||||
|
||||
SkIRect fRect;
|
||||
GrColorType fSrcColorType;
|
||||
GrColorType fDstColorType;
|
||||
SkAutoSTArray<16, GrMipLevel> fLevels;
|
||||
sk_sp<SkData> fStorage;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -195,8 +195,9 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
TestReadPixels(reporter, context0, surfaceContext.get(), pixels.get(), "EGLImageTest-read");
|
||||
//TestReadPixels(reporter, context0, surfaceContext.get(), pixels.get(), "EGLImageTest-read");
|
||||
|
||||
SkDebugf("type: %d\n", surfaceContext->asTextureProxy()->textureType());
|
||||
// We should not be able to write to an EXTERNAL texture
|
||||
TestWritePixels(reporter, context0, surfaceContext.get(), false, "EGLImageTest-write");
|
||||
|
||||
|
@ -598,7 +598,7 @@ static void run_test(GrDirectContext* dContext, const char* testName,
|
||||
return;
|
||||
}
|
||||
|
||||
auto [resultPM, resultStorage] = GrPixmap::Allocate(gold.info());
|
||||
GrPixmap resultPM = GrPixmap::Allocate(gold.info());
|
||||
rtc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));
|
||||
rtc->addDrawOp(GrMeshTestOp::Make(dContext, prepareFn, executeFn));
|
||||
|
||||
|
@ -58,7 +58,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RenderTargetContextTest, reporter, ctxInfo) {
|
||||
check_instantiation_status(reporter, rtCtx.get(), false);
|
||||
|
||||
SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(kSize, kSize);
|
||||
auto [dstPM, dstStorage] = GrPixmap::Allocate(dstInfo);
|
||||
GrPixmap dstPM = GrPixmap::Allocate(dstInfo);
|
||||
|
||||
bool result = rtCtx->readPixels(dContext, dstPM, {0, 0});
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
|
@ -127,7 +127,7 @@ void read_and_check_pixels(skiatest::Reporter* reporter,
|
||||
const SkImageInfo& dstInfo, CheckFn checker, float error,
|
||||
const char* subtestName) {
|
||||
auto [w, h] = dstInfo.dimensions();
|
||||
auto [readPM, readStorage] = GrPixmap::Allocate(dstInfo);
|
||||
GrPixmap readPM = GrPixmap::Allocate(dstInfo);
|
||||
memset(readPM.addr(), 0, sizeof(uint32_t)*w*h);
|
||||
|
||||
if (!sContext->readPixels(dContext, readPM, {0, 0})) {
|
||||
|
Loading…
Reference in New Issue
Block a user