chromium/third_party/skia/src/gpu/graphite/Context.cpp

/*
 * 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 "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();

    // This is roughly equivalent to the logic taken in asyncRescaleAndRead(SkSurface) to either
    // try the image-based readback (with copy-as-draw fallbacks) or read the texture directly
    // if it supports reading.
    if (!fContext->fSharedContext->caps()->supportsReadPixels(textureProxy->textureInfo())) {
        // Since this is a synchronous testing-only API, callers should have flushed any pending
        // work that modifies this texture proxy already. This means we don't have to worry about
        // re-wrapping the proxy in a new Image (that wouldn't tbe connected to any Device, etc.).
        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(/*recorder=*/nullptr, params);
        }
    } else {
        fContext->asyncReadTexture(/*recorder=*/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) {}

} // namespace skgpu::graphite