1/*
2 * Copyright 2017 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 "src/gpu/GrOnFlushResourceProvider.h"
9
10#include "include/private/GrRecordingContext.h"
11#include "src/gpu/GrContextPriv.h"
12#include "src/gpu/GrDrawingManager.h"
13#include "src/gpu/GrProxyProvider.h"
14#include "src/gpu/GrRecordingContextPriv.h"
15#include "src/gpu/GrRenderTargetContext.h"
16#include "src/gpu/GrSurfaceProxy.h"
17#include "src/gpu/GrTextureResolveRenderTask.h"
18
19std::unique_ptr<GrRenderTargetContext> GrOnFlushResourceProvider::makeRenderTargetContext(
20 sk_sp<GrSurfaceProxy> proxy, GrSurfaceOrigin origin, GrColorType colorType,
21 sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props) {
22 // Since this is at flush time and these won't be allocated for us by the GrResourceAllocator
23 // we have to manually ensure it is allocated here.
24 if (!this->instatiateProxy(proxy.get())) {
25 return nullptr;
26 }
27
28 auto context = fDrawingMgr->getContext();
29
30 if (!proxy->asRenderTargetProxy()) {
31 return nullptr;
32 }
33
34 auto renderTargetContext = GrRenderTargetContext::Make(
35 context, colorType, std::move(colorSpace), std::move(proxy),
36 origin, props, false);
37
38 if (!renderTargetContext) {
39 return nullptr;
40 }
41
42 renderTargetContext->discard();
43
44 // FIXME: http://skbug.com/9357: This breaks if the renderTargetContext splits its opsTask.
45 fDrawingMgr->fOnFlushRenderTasks.push_back(sk_ref_sp(renderTargetContext->getOpsTask()));
46
47 return renderTargetContext;
48}
49
50void GrOnFlushResourceProvider::addTextureResolveTask(sk_sp<GrTextureProxy> textureProxy,
51 GrSurfaceProxy::ResolveFlags resolveFlags) {
52 // Since we are bypassing normal DAG operation, we need to ensure the textureProxy's last render
53 // task gets closed before making a texture resolve task. makeClosed is what will mark msaa and
54 // mipmaps dirty.
55 if (GrRenderTask* renderTask = textureProxy->getLastRenderTask()) {
56 renderTask->makeClosed(*this->caps());
57 }
58 auto task = static_cast<GrTextureResolveRenderTask*>(fDrawingMgr->fOnFlushRenderTasks.push_back(
59 sk_make_sp<GrTextureResolveRenderTask>()).get());
60 task->addProxy(std::move(textureProxy), resolveFlags, *this->caps());
61 task->makeClosed(*this->caps());
62}
63
64bool GrOnFlushResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key,
65 GrTextureProxy* proxy) {
66 auto proxyProvider = fDrawingMgr->getContext()->priv().proxyProvider();
67 return proxyProvider->assignUniqueKeyToProxy(key, proxy);
68}
69
70void GrOnFlushResourceProvider::removeUniqueKeyFromProxy(GrTextureProxy* proxy) {
71 auto proxyProvider = fDrawingMgr->getContext()->priv().proxyProvider();
72 proxyProvider->removeUniqueKeyFromProxy(proxy);
73}
74
75void GrOnFlushResourceProvider::processInvalidUniqueKey(const GrUniqueKey& key) {
76 auto proxyProvider = fDrawingMgr->getContext()->priv().proxyProvider();
77 proxyProvider->processInvalidUniqueKey(key, nullptr,
78 GrProxyProvider::InvalidateGPUResource::kYes);
79}
80
81sk_sp<GrTextureProxy> GrOnFlushResourceProvider::findOrCreateProxyByUniqueKey(
82 const GrUniqueKey& key,
83 UseAllocator useAllocator) {
84 auto proxyProvider = fDrawingMgr->getContext()->priv().proxyProvider();
85 return proxyProvider->findOrCreateProxyByUniqueKey(key, useAllocator);
86}
87
88bool GrOnFlushResourceProvider::instatiateProxy(GrSurfaceProxy* proxy) {
89 SkASSERT(proxy->canSkipResourceAllocator());
90
91 // TODO: this class should probably just get a GrDirectContext
92 auto direct = fDrawingMgr->getContext()->priv().asDirectContext();
93 if (!direct) {
94 return false;
95 }
96
97 auto resourceProvider = direct->priv().resourceProvider();
98
99 if (proxy->isLazy()) {
100 return proxy->priv().doLazyInstantiation(resourceProvider);
101 }
102
103 return proxy->instantiate(resourceProvider);
104}
105
106sk_sp<GrGpuBuffer> GrOnFlushResourceProvider::makeBuffer(GrGpuBufferType intendedType, size_t size,
107 const void* data) {
108 // TODO: this class should probably just get a GrDirectContext
109 auto direct = fDrawingMgr->getContext()->priv().asDirectContext();
110 if (!direct) {
111 return nullptr;
112 }
113
114 auto resourceProvider = direct->priv().resourceProvider();
115
116 return sk_sp<GrGpuBuffer>(
117 resourceProvider->createBuffer(size, intendedType, kDynamic_GrAccessPattern, data));
118}
119
120sk_sp<const GrGpuBuffer> GrOnFlushResourceProvider::findOrMakeStaticBuffer(
121 GrGpuBufferType intendedType, size_t size, const void* data, const GrUniqueKey& key) {
122 // TODO: class should probably just get a GrDirectContext
123 auto direct = fDrawingMgr->getContext()->priv().asDirectContext();
124 if (!direct) {
125 return nullptr;
126 }
127
128 auto resourceProvider = direct->priv().resourceProvider();
129
130 return resourceProvider->findOrMakeStaticBuffer(intendedType, size, data, key);
131}
132
133uint32_t GrOnFlushResourceProvider::contextID() const {
134 return fDrawingMgr->getContext()->priv().contextID();
135}
136
137const GrCaps* GrOnFlushResourceProvider::caps() const {
138 return fDrawingMgr->getContext()->priv().caps();
139}
140
141GrOpMemoryPool* GrOnFlushResourceProvider::opMemoryPool() const {
142 return fDrawingMgr->getContext()->priv().opMemoryPool();
143}
144
145void GrOnFlushResourceProvider::printWarningMessage(const char* msg) const {
146 fDrawingMgr->getContext()->priv().printWarningMessage(msg);
147}
148