|
30 | 30 | #include "src/gpu/GrTexturePriv.h" |
31 | 31 | #include "src/gpu/GrTextureProxy.h" |
32 | 32 | #include "src/gpu/GrTextureProxyPriv.h" |
| 33 | +#include "src/gpu/GrTextureResolveRenderTask.h" |
33 | 34 | #include "src/gpu/GrTracing.h" |
34 | 35 | #include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h" |
35 | 36 | #include "src/gpu/text/GrTextContext.h" |
@@ -81,8 +82,16 @@ bool GrDrawingManager::RenderTaskDAG::isUsed(GrSurfaceProxy* proxy) const { |
81 | 82 | return false; |
82 | 83 | } |
83 | 84 |
|
84 | | -void GrDrawingManager::RenderTaskDAG::add(sk_sp<GrRenderTask> renderTask) { |
85 | | - fRenderTasks.emplace_back(std::move(renderTask)); |
| 85 | +GrRenderTask* GrDrawingManager::RenderTaskDAG::add(sk_sp<GrRenderTask> renderTask) { |
| 86 | + return fRenderTasks.emplace_back(std::move(renderTask)).get(); |
| 87 | +} |
| 88 | + |
| 89 | +GrRenderTask* GrDrawingManager::RenderTaskDAG::addBeforeLast(sk_sp<GrRenderTask> renderTask) { |
| 90 | + SkASSERT(!fRenderTasks.empty()); |
| 91 | + // Release 'fRenderTasks.back()' and grab the raw pointer. If we pass in a reference to an array |
| 92 | + // element, and the array grows during emplace_back, then the reference will become invalidated. |
| 93 | + fRenderTasks.emplace_back(fRenderTasks.back().release()); |
| 94 | + return (fRenderTasks[fRenderTasks.count() - 2] = std::move(renderTask)).get(); |
86 | 95 | } |
87 | 96 |
|
88 | 97 | void GrDrawingManager::RenderTaskDAG::add(const SkTArray<sk_sp<GrRenderTask>>& opLists) { |
@@ -499,17 +508,18 @@ GrSemaphoresSubmitted GrDrawingManager::flushSurfaces(GrSurfaceProxy* proxies[], |
499 | 508 | if (!proxies[i]->isInstantiated()) { |
500 | 509 | return result; |
501 | 510 | } |
502 | | - } |
503 | | - |
504 | | - for (int i = 0; i < numProxies; ++i) { |
505 | 511 | GrSurface* surface = proxies[i]->peekSurface(); |
506 | 512 | if (auto* rt = surface->asRenderTarget()) { |
507 | 513 | gpu->resolveRenderTarget(rt); |
508 | 514 | } |
509 | | - if (auto* tex = surface->asTexture()) { |
510 | | - if (tex->texturePriv().mipMapped() == GrMipMapped::kYes && |
511 | | - tex->texturePriv().mipMapsAreDirty()) { |
512 | | - gpu->regenerateMipMapLevels(tex); |
| 515 | + // If, after a flush, any of the proxies of interest have dirty mipmaps, regenerate them in |
| 516 | + // case their backend textures are being stolen. |
| 517 | + // (This special case is exercised by the ReimportImageTextureWithMipLevels test.) |
| 518 | + // FIXME: It may be more ideal to plumb down a "we're going to steal the backends" flag. |
| 519 | + if (auto* textureProxy = proxies[i]->asTextureProxy()) { |
| 520 | + if (textureProxy->mipMapsAreDirty()) { |
| 521 | + gpu->regenerateMipMapLevels(textureProxy->peekTexture()); |
| 522 | + textureProxy->markMipMapsClean(); |
513 | 523 | } |
514 | 524 | } |
515 | 525 | } |
@@ -669,6 +679,24 @@ sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(sk_sp<GrTextureProxy> |
669 | 679 | return opList; |
670 | 680 | } |
671 | 681 |
|
| 682 | +GrRenderTask* GrDrawingManager::newTextureResolveRenderTask( |
| 683 | + sk_sp<GrTextureProxy> textureProxy, GrTextureResolveFlags flags, const GrCaps& caps) { |
| 684 | + // Unlike in the "new opList" cases, we do not want to close the active opList, nor (if we are |
| 685 | + // in sorting and opList reduction mode) the render tasks that depend on the proxy's current |
| 686 | + // state. This is because those opLists can still receive new ops and because if they refer to |
| 687 | + // the mipmapped version of 'textureProxy', they will then come to depend on the render task |
| 688 | + // being created here. |
| 689 | + // NOTE: In either case, 'textureProxy' should already be closed at this point (i.e., its state |
| 690 | + // is finished)) |
| 691 | + SkASSERT(!textureProxy->getLastRenderTask() || textureProxy->getLastRenderTask()->isClosed()); |
| 692 | + auto textureResolveTask = GrTextureResolveRenderTask::Make(textureProxy, flags, caps); |
| 693 | + SkASSERT(textureProxy->getLastRenderTask() == textureResolveTask.get()); |
| 694 | + // Add the new textureResolveTask before the fActiveOpList (if not in |
| 695 | + // sorting/opList-splitting-reduction mode) because it will depend upon this resolve task. |
| 696 | + // NOTE: Putting it here will also reduce the amount of work required by the topological sort. |
| 697 | + return fDAG.addBeforeLast(std::move(textureResolveTask)); |
| 698 | +} |
| 699 | + |
672 | 700 | GrTextContext* GrDrawingManager::getTextContext() { |
673 | 701 | if (!fTextContext) { |
674 | 702 | fTextContext = GrTextContext::Make(fOptionsForTextContext); |
|
0 commit comments