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