1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/gpu/GrContextThreadSafeProxy.h"
9#include "src/gpu/GrContextThreadSafeProxyPriv.h"
10
11#include "include/core/SkSurfaceCharacterization.h"
12#include "include/gpu/GrContext.h"
13#include "src/gpu/GrBaseContextPriv.h"
14#include "src/gpu/GrCaps.h"
15#include "src/gpu/effects/GrSkSLFP.h"
16#include "src/image/SkSurface_Gpu.h"
17
18#ifdef SK_VULKAN
19#include "src/gpu/vk/GrVkCaps.h"
20#endif
21
22GrContextThreadSafeProxy::GrContextThreadSafeProxy(GrBackendApi backend,
23 const GrContextOptions& options,
24 uint32_t contextID)
25 : INHERITED(backend, options, contextID) {
26}
27
28GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
29
30bool GrContextThreadSafeProxy::init(sk_sp<const GrCaps> caps) {
31 return INHERITED::init(std::move(caps));
32}
33
34SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
35 size_t cacheMaxResourceBytes,
36 const SkImageInfo& ii, const GrBackendFormat& backendFormat,
37 int sampleCnt, GrSurfaceOrigin origin,
38 const SkSurfaceProps& surfaceProps,
39 bool isMipMapped, bool willUseGLFBO0, bool isTextureable,
40 GrProtected isProtected) {
41 if (!backendFormat.isValid()) {
42 return SkSurfaceCharacterization(); // return an invalid characterization
43 }
44
45 SkASSERT(isTextureable || !isMipMapped);
46
47 if (GrBackendApi::kOpenGL != backendFormat.backend() && willUseGLFBO0) {
48 // The willUseGLFBO0 flags can only be used for a GL backend.
49 return SkSurfaceCharacterization(); // return an invalid characterization
50 }
51
52 if (!this->caps()->mipMapSupport()) {
53 isMipMapped = false;
54 }
55
56 GrColorType grColorType = SkColorTypeToGrColorType(ii.colorType());
57
58 if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, backendFormat)) {
59 return SkSurfaceCharacterization(); // return an invalid characterization
60 }
61
62 if (!this->caps()->isFormatAsColorTypeRenderable(grColorType, backendFormat, sampleCnt)) {
63 return SkSurfaceCharacterization(); // return an invalid characterization
64 }
65
66 sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendFormat);
67 SkASSERT(sampleCnt);
68
69 if (willUseGLFBO0 && isTextureable) {
70 return SkSurfaceCharacterization(); // return an invalid characterization
71 }
72
73 if (isTextureable && !this->caps()->isFormatTexturable(backendFormat)) {
74 // Skia doesn't agree that this is textureable.
75 return SkSurfaceCharacterization(); // return an invalid characterization
76 }
77
78 if (GrBackendApi::kVulkan == backendFormat.backend()) {
79 if (GrBackendApi::kVulkan != this->backend()) {
80 return SkSurfaceCharacterization(); // return an invalid characterization
81 }
82
83#ifdef SK_VULKAN
84 const GrVkCaps* vkCaps = (const GrVkCaps*) this->caps();
85
86 // The protection status of the characterization and the context need to match
87 if (isProtected != GrProtected(vkCaps->supportsProtectedMemory())) {
88 return SkSurfaceCharacterization(); // return an invalid characterization
89 }
90#endif
91 }
92
93 return SkSurfaceCharacterization(sk_ref_sp<GrContextThreadSafeProxy>(this),
94 cacheMaxResourceBytes, ii, backendFormat,
95 origin, sampleCnt,
96 SkSurfaceCharacterization::Textureable(isTextureable),
97 SkSurfaceCharacterization::MipMapped(isMipMapped),
98 SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0),
99 SkSurfaceCharacterization::VulkanSecondaryCBCompatible(false),
100 isProtected,
101 surfaceProps);
102}
103
104////////////////////////////////////////////////////////////////////////////////
105sk_sp<GrContextThreadSafeProxy> GrContextThreadSafeProxyPriv::Make(
106 GrBackendApi backend,
107 const GrContextOptions& options,
108 uint32_t contextID,
109 sk_sp<const GrCaps> caps) {
110 sk_sp<GrContextThreadSafeProxy> proxy(new GrContextThreadSafeProxy(backend, options,
111 contextID));
112
113 if (!proxy->init(std::move(caps))) {
114 return nullptr;
115 }
116 return proxy;
117}
118
119