Flutter Engine
The Flutter Engine
GrTextureResolveRenderTask.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
8
10#include "include/gpu/GrTypes.h"
21
22#include <algorithm>
23#include <cstddef>
24#include <utility>
25
26class GrRenderTarget;
27
29 sk_sp<GrSurfaceProxy> proxyRef,
31 const GrCaps& caps) {
33 GrSurfaceProxy* proxy = proxyRef.get();
34 Resolve* resolve;
35 bool newProxy = false;
36
37 // We might just need to update the flags for an existing dependency.
38 if (auto found = std::find(fTargets.begin(), fTargets.end(), proxyRef);
39 found != fTargets.end()) {
40 size_t index = found - fTargets.begin();
41 resolve = &fResolves[index];
42 newFlags = ~resolve->fFlags & flags;
43 resolve->fFlags |= flags;
44 } else {
45 // Ensure the last render task that operated on the proxy is closed. That's where msaa and
46 // mipmaps should have been marked dirty.
47 SkASSERT(!drawingMgr->getLastRenderTask(proxy)
48 || drawingMgr->getLastRenderTask(proxy)->isClosed());
50 resolve = &fResolves.emplace_back(flags);
51 newProxy = true;
52 }
53
55 GrRenderTargetProxy* renderTargetProxy = proxy->asRenderTargetProxy();
56 SkASSERT(renderTargetProxy);
57 SkASSERT(renderTargetProxy->isMSAADirty());
58 resolve->fMSAAResolveRect = renderTargetProxy->msaaDirtyRect();
59 renderTargetProxy->markMSAAResolved();
60 }
61
63 GrTextureProxy* textureProxy = proxy->asTextureProxy();
64 SkASSERT(skgpu::Mipmapped::kYes == textureProxy->mipmapped());
65 SkASSERT(textureProxy->mipmapsAreDirty());
66 textureProxy->markMipmapsClean();
67 }
68
69 // We must do this after updating the proxy state because of assertions that the proxy isn't
70 // dirty.
71 if (newProxy) {
72 // Add the proxy as a dependency: We will read the existing contents of this texture while
73 // generating mipmap levels and/or resolving MSAA.
74 this->addDependency(
75 drawingMgr, proxy, skgpu::Mipmapped::kNo, GrTextureResolveManager(nullptr), caps);
76 this->addTarget(drawingMgr, GrSurfaceProxyView(std::move(proxyRef)));
77 }
78}
79
80void GrTextureResolveRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
81 // This renderTask doesn't have "normal" ops, however we still need to add intervals so
82 // fEndOfOpsTaskOpIndices will remain in sync. We create fake op#'s to capture the fact that we
83 // manipulate the resolve proxies.
84 auto fakeOp = alloc->curOp();
85 SkASSERT(fResolves.size() == this->numTargets());
87 alloc->addInterval(target.get(), fakeOp, fakeOp, GrResourceAllocator::ActualUse::kYes,
89 }
90 alloc->incOps();
91}
92
93bool GrTextureResolveRenderTask::onExecute(GrOpFlushState* flushState) {
94 // Resolve all msaa back-to-back, before regenerating mipmaps.
95 SkASSERT(fResolves.size() == this->numTargets());
96 for (int i = 0; i < fResolves.size(); ++i) {
97 const Resolve& resolve = fResolves[i];
98 if (GrSurfaceProxy::ResolveFlags::kMSAA & resolve.fFlags) {
99 GrSurfaceProxy* proxy = this->target(i);
100 // peekRenderTarget might be null if there was an instantiation error.
101 if (GrRenderTarget* renderTarget = proxy->peekRenderTarget()) {
102 flushState->gpu()->resolveRenderTarget(renderTarget, resolve.fMSAAResolveRect);
103 }
104 }
105 }
106 // Regenerate all mipmaps back-to-back.
107 for (int i = 0; i < fResolves.size(); ++i) {
108 const Resolve& resolve = fResolves[i];
109 if (GrSurfaceProxy::ResolveFlags::kMipMaps & resolve.fFlags) {
110 // peekTexture might be null if there was an instantiation error.
111 GrTexture* texture = this->target(i)->peekTexture();
112 if (texture && texture->mipmapsAreDirty()) {
113 flushState->gpu()->regenerateMipMapLevels(texture);
114 SkASSERT(!texture->mipmapsAreDirty());
115 }
116 }
117 }
118
119 return true;
120}
121
122#ifdef SK_DEBUG
123void GrTextureResolveRenderTask::visitProxies_debugOnly(const GrVisitProxyFunc&) const {}
124#endif
125
126#if defined(GR_TEST_UTILS)
128GrTextureResolveRenderTask::flagsForProxy(sk_sp<GrSurfaceProxy> proxy) const {
129 if (auto found = std::find(fTargets.begin(), fTargets.end(), proxy);
130 found != fTargets.end()) {
131 return fResolves[found - fTargets.begin()].fFlags;
132 }
134}
135#endif
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
Definition: GrTypesPriv.h:943
#define SkASSERT(cond)
Definition: SkAssert.h:116
int find(T *array, int N, T item)
Definition: GrCaps.h:57
GrRenderTask * getLastRenderTask(const GrSurfaceProxy *) const
bool regenerateMipMapLevels(GrTexture *)
Definition: GrGpu.cpp:632
void resolveRenderTarget(GrRenderTarget *, const SkIRect &resolveRect)
Definition: GrGpu.cpp:659
const SkIRect & msaaDirtyRect() const
GrSurfaceProxy * target(int i) const
Definition: GrRenderTask.h:104
bool isClosed() const
Definition: GrRenderTask.h:56
void addDependency(GrDrawingManager *, GrSurfaceProxy *dependedOn, skgpu::Mipmapped, GrTextureResolveManager, const GrCaps &caps)
skia_private::STArray< 1, sk_sp< GrSurfaceProxy > > fTargets
Definition: GrRenderTask.h:182
void addTarget(GrDrawingManager *dm, const GrSurfaceProxyView &view)
Definition: GrRenderTask.h:166
void addInterval(GrSurfaceProxy *, unsigned int start, unsigned int end, ActualUse actualUse, AllowRecycling SkDEBUGCODE(, bool isDirectDstRead=false))
unsigned int curOp() const
virtual GrRenderTargetProxy * asRenderTargetProxy()
GrTexture * peekTexture() const
virtual GrTextureProxy * asTextureProxy()
GrRenderTarget * peekRenderTarget() const
void markMipmapsClean()
skgpu::Mipmapped mipmapped() const
bool mipmapsAreDirty() const
void addProxy(GrDrawingManager *, sk_sp< GrSurfaceProxy > proxy, GrSurfaceProxy::ResolveFlags, const GrCaps &)
T * get() const
Definition: SkRefCnt.h:303
int size() const
Definition: SkTArray.h:421
T & emplace_back(Args &&... args)
Definition: SkTArray.h:248
FlutterSemanticsFlag flags
FlTexture * texture
static FunctionPtr Resolve(Thread *thread, Zone *zone, const GrowableArray< const Instance * > &caller_arguments, const Class &receiver_class, const String &name, const Array &descriptor)