1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include <memory>
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/gpu/GrContextThreadSafeProxy.h"
11cb93a386Sopenharmony_ci#include "src/gpu/GrContextThreadSafeProxyPriv.h"
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci#include "include/core/SkSurfaceCharacterization.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrBaseContextPriv.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrThreadSafeCache.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrThreadSafePipelineBuilder.h"
18cb93a386Sopenharmony_ci#include "src/gpu/effects/GrSkSLFP.h"
19cb93a386Sopenharmony_ci#include "src/image/SkSurface_Gpu.h"
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci#ifdef SK_VULKAN
22cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCaps.h"
23cb93a386Sopenharmony_ci#endif
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_cistatic int32_t next_id() {
26cb93a386Sopenharmony_ci    static std::atomic<int32_t> nextID{1};
27cb93a386Sopenharmony_ci    int32_t id;
28cb93a386Sopenharmony_ci    do {
29cb93a386Sopenharmony_ci        id = nextID.fetch_add(1, std::memory_order_relaxed);
30cb93a386Sopenharmony_ci    } while (id == SK_InvalidGenID);
31cb93a386Sopenharmony_ci    return id;
32cb93a386Sopenharmony_ci}
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ciGrContextThreadSafeProxy::GrContextThreadSafeProxy(GrBackendApi backend,
35cb93a386Sopenharmony_ci                                                   const GrContextOptions& options)
36cb93a386Sopenharmony_ci        : fBackend(backend), fOptions(options), fContextID(next_id()) {
37cb93a386Sopenharmony_ci}
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ciGrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_civoid GrContextThreadSafeProxy::init(sk_sp<const GrCaps> caps,
42cb93a386Sopenharmony_ci                                    sk_sp<GrThreadSafePipelineBuilder> pipelineBuilder) {
43cb93a386Sopenharmony_ci    fCaps = std::move(caps);
44cb93a386Sopenharmony_ci    fTextBlobCache = std::make_unique<GrTextBlobCache>(fContextID);
45cb93a386Sopenharmony_ci    fThreadSafeCache = std::make_unique<GrThreadSafeCache>();
46cb93a386Sopenharmony_ci    fPipelineBuilder = std::move(pipelineBuilder);
47cb93a386Sopenharmony_ci}
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ciSkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
50cb93a386Sopenharmony_ci                                     size_t cacheMaxResourceBytes,
51cb93a386Sopenharmony_ci                                     const SkImageInfo& ii, const GrBackendFormat& backendFormat,
52cb93a386Sopenharmony_ci                                     int sampleCnt, GrSurfaceOrigin origin,
53cb93a386Sopenharmony_ci                                     const SkSurfaceProps& surfaceProps,
54cb93a386Sopenharmony_ci                                     bool isMipMapped, bool willUseGLFBO0, bool isTextureable,
55cb93a386Sopenharmony_ci                                     GrProtected isProtected, bool vkRTSupportsInputAttachment,
56cb93a386Sopenharmony_ci                                     bool forVulkanSecondaryCommandBuffer) {
57cb93a386Sopenharmony_ci    SkASSERT(fCaps);
58cb93a386Sopenharmony_ci    if (!backendFormat.isValid()) {
59cb93a386Sopenharmony_ci        return {};
60cb93a386Sopenharmony_ci    }
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_ci    SkASSERT(isTextureable || !isMipMapped);
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ci    if (GrBackendApi::kOpenGL != backendFormat.backend() && willUseGLFBO0) {
65cb93a386Sopenharmony_ci        // The willUseGLFBO0 flags can only be used for a GL backend.
66cb93a386Sopenharmony_ci        return {};
67cb93a386Sopenharmony_ci    }
68cb93a386Sopenharmony_ci
69cb93a386Sopenharmony_ci    if (GrBackendApi::kVulkan != backendFormat.backend() &&
70cb93a386Sopenharmony_ci        (vkRTSupportsInputAttachment || forVulkanSecondaryCommandBuffer)) {
71cb93a386Sopenharmony_ci        // The vkRTSupportsInputAttachment and forVulkanSecondaryCommandBuffer flags can only be
72cb93a386Sopenharmony_ci        // used for a Vulkan backend.
73cb93a386Sopenharmony_ci        return {};
74cb93a386Sopenharmony_ci    }
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci    if (!fCaps->mipmapSupport()) {
77cb93a386Sopenharmony_ci        isMipMapped = false;
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ci    if (ii.width()  < 1 || ii.width()  > fCaps->maxRenderTargetSize() ||
81cb93a386Sopenharmony_ci        ii.height() < 1 || ii.height() > fCaps->maxRenderTargetSize()) {
82cb93a386Sopenharmony_ci        return {};
83cb93a386Sopenharmony_ci    }
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci    GrColorType grColorType = SkColorTypeToGrColorType(ii.colorType());
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ci    if (!fCaps->areColorTypeAndFormatCompatible(grColorType, backendFormat)) {
88cb93a386Sopenharmony_ci        return {};
89cb93a386Sopenharmony_ci    }
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ci    if (!fCaps->isFormatAsColorTypeRenderable(grColorType, backendFormat, sampleCnt)) {
92cb93a386Sopenharmony_ci        return {};
93cb93a386Sopenharmony_ci    }
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, backendFormat);
96cb93a386Sopenharmony_ci    SkASSERT(sampleCnt);
97cb93a386Sopenharmony_ci
98cb93a386Sopenharmony_ci    if (willUseGLFBO0 && isTextureable) {
99cb93a386Sopenharmony_ci        return {};
100cb93a386Sopenharmony_ci    }
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ci    if (isTextureable && !fCaps->isFormatTexturable(backendFormat, backendFormat.textureType())) {
103cb93a386Sopenharmony_ci        // Skia doesn't agree that this is textureable.
104cb93a386Sopenharmony_ci        return {};
105cb93a386Sopenharmony_ci    }
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci    if (forVulkanSecondaryCommandBuffer &&
108cb93a386Sopenharmony_ci        (isTextureable || isMipMapped || willUseGLFBO0 || vkRTSupportsInputAttachment)) {
109cb93a386Sopenharmony_ci        return {};
110cb93a386Sopenharmony_ci    }
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci    if (GrBackendApi::kVulkan == backendFormat.backend()) {
113cb93a386Sopenharmony_ci        if (GrBackendApi::kVulkan != fBackend) {
114cb93a386Sopenharmony_ci            return {};
115cb93a386Sopenharmony_ci        }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci#ifdef SK_VULKAN
118cb93a386Sopenharmony_ci        const GrVkCaps* vkCaps = (const GrVkCaps*) fCaps.get();
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci        // The protection status of the characterization and the context need to match
121cb93a386Sopenharmony_ci        if (isProtected != GrProtected(vkCaps->supportsProtectedMemory())) {
122cb93a386Sopenharmony_ci            return {};
123cb93a386Sopenharmony_ci        }
124cb93a386Sopenharmony_ci#endif
125cb93a386Sopenharmony_ci    }
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ci    return SkSurfaceCharacterization(
128cb93a386Sopenharmony_ci            sk_ref_sp<GrContextThreadSafeProxy>(this),
129cb93a386Sopenharmony_ci            cacheMaxResourceBytes, ii, backendFormat,
130cb93a386Sopenharmony_ci            origin, sampleCnt,
131cb93a386Sopenharmony_ci            SkSurfaceCharacterization::Textureable(isTextureable),
132cb93a386Sopenharmony_ci            SkSurfaceCharacterization::MipMapped(isMipMapped),
133cb93a386Sopenharmony_ci            SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0),
134cb93a386Sopenharmony_ci            SkSurfaceCharacterization::VkRTSupportsInputAttachment(vkRTSupportsInputAttachment),
135cb93a386Sopenharmony_ci            SkSurfaceCharacterization::VulkanSecondaryCBCompatible(forVulkanSecondaryCommandBuffer),
136cb93a386Sopenharmony_ci            isProtected,
137cb93a386Sopenharmony_ci            surfaceProps);
138cb93a386Sopenharmony_ci}
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ciGrBackendFormat GrContextThreadSafeProxy::defaultBackendFormat(SkColorType skColorType,
141cb93a386Sopenharmony_ci                                                               GrRenderable renderable) const {
142cb93a386Sopenharmony_ci    SkASSERT(fCaps);
143cb93a386Sopenharmony_ci    GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    GrBackendFormat format = fCaps->getDefaultBackendFormat(grColorType, renderable);
146cb93a386Sopenharmony_ci    if (!format.isValid()) {
147cb93a386Sopenharmony_ci        return GrBackendFormat();
148cb93a386Sopenharmony_ci    }
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_ci    SkASSERT(renderable == GrRenderable::kNo ||
151cb93a386Sopenharmony_ci             fCaps->isFormatAsColorTypeRenderable(grColorType, format));
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_ci    return format;
154cb93a386Sopenharmony_ci}
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ciGrBackendFormat GrContextThreadSafeProxy::compressedBackendFormat(SkImage::CompressionType c) const {
157cb93a386Sopenharmony_ci    SkASSERT(fCaps);
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ci    GrBackendFormat format = fCaps->getBackendFormatFromCompressionType(c);
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci    SkASSERT(!format.isValid() || fCaps->isFormatTexturable(format, GrTextureType::k2D));
162cb93a386Sopenharmony_ci    return format;
163cb93a386Sopenharmony_ci}
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_civoid GrContextThreadSafeProxy::abandonContext() {
166cb93a386Sopenharmony_ci    if (!fAbandoned.exchange(true)) {
167cb93a386Sopenharmony_ci        fTextBlobCache->freeAll();
168cb93a386Sopenharmony_ci    }
169cb93a386Sopenharmony_ci}
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_cibool GrContextThreadSafeProxy::abandoned() const {
172cb93a386Sopenharmony_ci    return fAbandoned;
173cb93a386Sopenharmony_ci}
174cb93a386Sopenharmony_ci
175cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////////
176cb93a386Sopenharmony_cisk_sp<GrContextThreadSafeProxy> GrContextThreadSafeProxyPriv::Make(
177cb93a386Sopenharmony_ci                             GrBackendApi backend,
178cb93a386Sopenharmony_ci                             const GrContextOptions& options) {
179cb93a386Sopenharmony_ci    return sk_sp<GrContextThreadSafeProxy>(new GrContextThreadSafeProxy(backend, options));
180cb93a386Sopenharmony_ci}
181cb93a386Sopenharmony_ci
182cb93a386Sopenharmony_civoid GrContextThreadSafeProxyPriv::init(sk_sp<const GrCaps> caps,
183cb93a386Sopenharmony_ci                                        sk_sp<GrThreadSafePipelineBuilder> builder) const {
184cb93a386Sopenharmony_ci    fProxy->init(std::move(caps), std::move(builder));
185cb93a386Sopenharmony_ci}
186cb93a386Sopenharmony_ci
187