#include "include/gpu/graphite/Context.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkTraceMemoryDump.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/private/base/SkOnce.h"
#include "src/base/SkRectMemcpy.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkColorFilterPriv.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkYUVMath.h"
#include "src/gpu/RefCntedCallback.h"
#include "src/gpu/graphite/AtlasProvider.h"
#include "src/gpu/graphite/BufferManager.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ClientMappedBufferManager.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/DrawAtlas.h"
#include "src/gpu/graphite/GlobalCache.h"
#include "src/gpu/graphite/GraphicsPipeline.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
#include "src/gpu/graphite/Image_Base_Graphite.h"
#include "src/gpu/graphite/Image_Graphite.h"
#include "src/gpu/graphite/KeyContext.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/QueueManager.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/RecordingPriv.h"
#include "src/gpu/graphite/Renderer.h"
#include "src/gpu/graphite/RendererProvider.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/ShaderCodeDictionary.h"
#include "src/gpu/graphite/SharedContext.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/TextureProxyView.h"
#include "src/gpu/graphite/TextureUtils.h"
#include "src/gpu/graphite/task/CopyTask.h"
#include "src/gpu/graphite/task/SynchronizeToCpuTask.h"
#include "src/gpu/graphite/task/UploadTask.h"
#include "src/image/SkSurface_Base.h"
#include "src/sksl/SkSLGraphiteModules.h"
#if defined(GPU_TEST_UTILS)
#include "src/gpu/graphite/ContextOptionsPriv.h"
#endif
namespace skgpu::graphite {
#define ASSERT_SINGLE_OWNER …
Context::ContextID Context::ContextID::Next() { … }
Context::Context(sk_sp<SharedContext> sharedContext,
std::unique_ptr<QueueManager> queueManager,
const ContextOptions& options)
: … { … }
Context::~Context() { … }
bool Context::finishInitialization() { … }
BackendApi Context::backend() const { … }
std::unique_ptr<Recorder> Context::makeRecorder(const RecorderOptions& options) { … }
std::unique_ptr<Recorder> Context::makeInternalRecorder() const { … }
bool Context::insertRecording(const InsertRecordingInfo& info) { … }
bool Context::submit(SyncToCpu syncToCpu) { … }
bool Context::hasUnfinishedGpuWork() const { … }
template <typename SrcPixels>
struct Context::AsyncParams { … };
template <typename ReadFn, typename... ExtraArgs>
void Context::asyncRescaleAndReadImpl(ReadFn Context::* asyncRead,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
const AsyncParams<SkImage>& params,
ExtraArgs... extraParams) { … }
void Context::asyncRescaleAndReadPixels(const SkImage* src,
const SkImageInfo& dstImageInfo,
const SkIRect& srcRect,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncRescaleAndReadPixels(const SkSurface* src,
const SkImageInfo& dstImageInfo,
const SkIRect& srcRect,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncReadPixels(std::unique_ptr<Recorder> recorder,
const AsyncParams<SkImage>& params) { … }
void Context::asyncReadTexture(std::unique_ptr<Recorder> recorder,
const AsyncParams<TextureProxy>& params,
const SkColorInfo& srcColorInfo) { … }
void Context::asyncRescaleAndReadPixelsYUV420(const SkImage* src,
SkYUVColorSpace yuvColorSpace,
sk_sp<SkColorSpace> dstColorSpace,
const SkIRect& srcRect,
const SkISize& dstSize,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncRescaleAndReadPixelsYUV420(const SkSurface* src,
SkYUVColorSpace yuvColorSpace,
sk_sp<SkColorSpace> dstColorSpace,
const SkIRect& srcRect,
const SkISize& dstSize,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncRescaleAndReadPixelsYUVA420(const SkImage* src,
SkYUVColorSpace yuvColorSpace,
sk_sp<SkColorSpace> dstColorSpace,
const SkIRect& srcRect,
const SkISize& dstSize,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncRescaleAndReadPixelsYUVA420(const SkSurface* src,
SkYUVColorSpace yuvColorSpace,
sk_sp<SkColorSpace> dstColorSpace,
const SkIRect& srcRect,
const SkISize& dstSize,
SkImage::RescaleGamma rescaleGamma,
SkImage::RescaleMode rescaleMode,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
void Context::asyncReadPixelsYUV420(std::unique_ptr<Recorder> recorder,
const AsyncParams<SkImage>& params,
SkYUVColorSpace yuvColorSpace) { … }
void Context::finalizeAsyncReadPixels(std::unique_ptr<Recorder> recorder,
SkSpan<PixelTransferResult> transferResults,
SkImage::ReadPixelsCallback callback,
SkImage::ReadPixelsContext callbackContext) { … }
Context::PixelTransferResult Context::transferPixels(Recorder* recorder,
const TextureProxy* srcProxy,
const SkColorInfo& srcColorInfo,
const SkColorInfo& dstColorInfo,
const SkIRect& srcRect) { … }
void Context::checkForFinishedWork(SyncToCpu syncToCpu) { … }
void Context::checkAsyncWorkCompletion() { … }
void Context::deleteBackendTexture(const BackendTexture& texture) { … }
void Context::freeGpuResources() { … }
void Context::performDeferredCleanup(std::chrono::milliseconds msNotUsed) { … }
size_t Context::currentBudgetedBytes() const { … }
size_t Context::currentPurgeableBytes() const { … }
size_t Context::maxBudgetedBytes() const { … }
void Context::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { … }
bool Context::isDeviceLost() const { … }
int Context::maxTextureSize() const { … }
bool Context::supportsProtectedContent() const { … }
#if defined(GPU_TEST_UTILS)
bool ContextPriv::readPixels(const SkPixmap& pm,
const TextureProxy* textureProxy,
const SkImageInfo& srcImageInfo,
int srcX, int srcY) {
auto rect = SkIRect::MakeXYWH(srcX, srcY, pm.width(), pm.height());
struct AsyncContext {
bool fCalled = false;
std::unique_ptr<const SkImage::AsyncReadResult> fResult;
} asyncContext;
auto asyncCallback = [](void* c, std::unique_ptr<const SkImage::AsyncReadResult> out) {
auto context = static_cast<AsyncContext*>(c);
context->fResult = std::move(out);
context->fCalled = true;
};
const SkColorInfo& srcColorInfo = srcImageInfo.colorInfo();
if (!fContext->fSharedContext->caps()->supportsReadPixels(textureProxy->textureInfo())) {
sk_sp<SkImage> image{new Image(TextureProxyView(sk_ref_sp(textureProxy)), srcColorInfo)};
Context::AsyncParams<SkImage> params {image.get(), rect, pm.info(),
asyncCallback, &asyncContext};
if (!params.validate()) {
params.fail();
} else {
fContext->asyncReadPixels(nullptr, params);
}
} else {
fContext->asyncReadTexture(nullptr,
{textureProxy, rect, pm.info(), asyncCallback, &asyncContext},
srcImageInfo.colorInfo());
}
if (fContext->fSharedContext->caps()->allowCpuSync()) {
fContext->submit(SyncToCpu::kYes);
} else {
fContext->submit(SyncToCpu::kNo);
if (fContext->fSharedContext->backend() == BackendApi::kDawn) {
while (!asyncContext.fCalled) {
fContext->fSharedContext->deviceTick(fContext);
}
} else {
SK_ABORT("Only Dawn supports non-syncing contexts.");
}
}
SkASSERT(asyncContext.fCalled);
if (!asyncContext.fResult) {
return false;
}
SkRectMemcpy(pm.writable_addr(), pm.rowBytes(), asyncContext.fResult->data(0),
asyncContext.fResult->rowBytes(0), pm.info().minRowBytes(),
pm.height());
return true;
}
void ContextPriv::deregisterRecorder(const Recorder* recorder) {
SKGPU_ASSERT_SINGLE_OWNER(fContext->singleOwner())
for (auto it = fContext->fTrackedRecorders.begin();
it != fContext->fTrackedRecorders.end();
it++) {
if (*it == recorder) {
fContext->fTrackedRecorders.erase(it);
return;
}
}
}
bool ContextPriv::supportsPathRendererStrategy(PathRendererStrategy strategy) {
AtlasProvider::PathAtlasFlagsBitMask pathAtlasFlags =
AtlasProvider::QueryPathAtlasSupport(this->caps());
switch (strategy) {
case PathRendererStrategy::kDefault:
return true;
case PathRendererStrategy::kComputeAnalyticAA:
case PathRendererStrategy::kComputeMSAA16:
case PathRendererStrategy::kComputeMSAA8:
return SkToBool(pathAtlasFlags & AtlasProvider::PathAtlasFlags::kCompute);
case PathRendererStrategy::kRasterAA:
return SkToBool(pathAtlasFlags & AtlasProvider::PathAtlasFlags::kRaster);
case PathRendererStrategy::kTessellation:
return true;
}
return false;
}
#endif
std::unique_ptr<Context> ContextCtorAccessor::MakeContext(
sk_sp<SharedContext> sharedContext,
std::unique_ptr<QueueManager> queueManager,
const ContextOptions& options) { … }
}