void GrContext::DrawingMgr::cleanup() { SkSafeSetNull(fDrawTarget); for (int i = 0; i < kNumPixelGeometries; ++i) { SkSafeSetNull(fDrawContext[i][0]); SkSafeSetNull(fDrawContext[i][1]); } }
void GrContext::freeGpuResources() { this->flush(); fBatchFontCache->freeAll(); fLayerCache->freeAll(); // a path renderer may be holding onto resources SkSafeSetNull(fPathRendererChain); SkSafeSetNull(fSoftwarePathRenderer); fResourceCache->purgeAllUnlocked(); }
void GrContext::DrawingMgr::abandon() { SkSafeSetNull(fDrawTarget); for (int i = 0; i < kNumPixelGeometries; ++i) { for (int j = 0; j < kNumDFTOptions; ++j) { if (fDrawContext[i][j]) { SkSafeSetNull(fDrawContext[i][j]->fDrawTarget); SkSafeSetNull(fDrawContext[i][j]); } } } }
SkCanvas* SkPicture::beginRecording(int width, int height, uint32_t recordingFlags) { if (fPlayback) { SkDELETE(fPlayback); fPlayback = NULL; } SkSafeUnref(fAccelData); SkSafeSetNull(fRecord); // Must be set before calling createBBoxHierarchy fWidth = width; fHeight = height; const SkISize size = SkISize::Make(width, height); if (recordingFlags & kOptimizeForClippedPlayback_RecordingFlag) { SkBBoxHierarchy* tree = this->createBBoxHierarchy(); SkASSERT(NULL != tree); fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordingFlags, tree)); tree->unref(); } else { fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags)); } fRecord->beginRecording(); return fRecord; }
void SkPicture::clone(SkPicture* pictures, int count) const { SkPictCopyInfo copyInfo; for (int i = 0; i < count; i++) { SkPicture* clone = &pictures[i]; clone->fWidth = fWidth; clone->fHeight = fHeight; SkSafeSetNull(clone->fRecord); SkDELETE(clone->fPlayback); /* We want to copy the src's playback. However, if that hasn't been built yet, we need to fake a call to endRecording() without actually calling it (since it is destructive, and we don't want to change src). */ if (fPlayback) { clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, ©Info)); } else if (fRecord) { // here we do a fake src.endRecording() clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, true)); } else { clone->fPlayback = NULL; } } }
GrGpu::~GrGpu() { SkSafeSetNull(fQuadIndexBuffer); delete fVertexPool; fVertexPool = NULL; delete fIndexPool; fIndexPool = NULL; }
void GrBitmapTextContext::flushGlyphs() { if (NULL == fDrawTarget) { return; } GrDrawState* drawState = fDrawTarget->drawState(); GrDrawState::AutoRestoreEffects are(drawState); drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); if (fCurrVertex > 0) { // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); SkASSERT(fCurrTexture); GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); // This effect could be stored with one of the cache objects (atlas?) drawState->addCoverageEffect( GrCustomCoordsTextureEffect::Create(fCurrTexture, params), kGlyphCoordsAttributeIndex)->unref(); if (NULL != fStrike && kARGB_GrMaskFormat == fStrike->getMaskFormat()) { drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); drawState->setColor(0xffffffff); } else if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { GrPrintf("LCD Text will not draw correctly.\n"); } // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState->setColor(SkColorSetARGB(a, a, a, a)); // paintColor drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor())); drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); } else { // set back to normal in case we took LCD path previously. drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); drawState->setColor(fPaint.getColor()); } int nGlyphs = fCurrVertex / 4; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, nGlyphs, 4, 6, &fVertexBounds); fDrawTarget->resetVertexSource(); fVertices = NULL; fMaxVertices = 0; fCurrVertex = 0; fVertexBounds.setLargestInverted(); SkSafeSetNull(fCurrTexture); } }
void GrDrawingManager::freeGpuResources() { // a path renderer may be holding onto resources delete fPathRendererChain; fPathRendererChain = nullptr; SkSafeSetNull(fSoftwarePathRenderer); for (int i = 0; i < fOpLists.count(); ++i) { fOpLists[i]->freeGpuResources(); } }
void GrRenderTarget::onAbandon() { SkSafeSetNull(fStencilAttachment); // The contents of this renderTarget are gone/invalid. It isn't useful to point back // the creating drawTarget. this->setLastDrawTarget(nullptr); INHERITED::onAbandon(); }
void GrContext::abandonContext() { fResourceProvider->abandon(); // abandon first to so destructors // don't try to free the resources in the API. fResourceCache->abandonAll(); fGpu->contextAbandoned(); // a path renderer may be holding onto resources that // are now unusable SkSafeSetNull(fPathRendererChain); SkSafeSetNull(fSoftwarePathRenderer); fDrawingMgr.abandon(); fBatchFontCache->freeAll(); fLayerCache->freeAll(); fTextBlobCache->freeAll(); }
void SkPicture::endRecording() { if (NULL == fPlayback) { if (NULL != fRecord) { fRecord->endRecording(); fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); SkSafeSetNull(fRecord); } } SkASSERT(NULL == fRecord); }
void GrContext::DrawingMgr::cleanup() { SkSafeSetNull(fDrawTarget); delete fNVPRTextContext; fNVPRTextContext = nullptr; for (int i = 0; i < kNumPixelGeometries; ++i) { delete fTextContexts[i][0]; fTextContexts[i][0] = nullptr; delete fTextContexts[i][1]; fTextContexts[i][1] = nullptr; } }
void GrDistanceFieldTextContext::flush() { if (NULL == fDrawTarget) { return; } if (fCurrVertex > 0) { GrPipelineBuilder pipelineBuilder; pipelineBuilder.setFromPaint(fPaint, fRenderTarget, fClip); // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); // get our current color SkColor filteredColor; SkColorFilter* colorFilter = fSkPaint.getColorFilter(); if (colorFilter) { filteredColor = colorFilter->filterColor(fSkPaint.getColor()); } else { filteredColor = fSkPaint.getColor(); } this->setupCoverageEffect(filteredColor); // Set draw state if (fUseLCDText) { // TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD // processor if the xp can support it. For now we will simply assume that if // fUseLCDText is true, then we have a known color output. const GrXPFactory* xpFactory = pipelineBuilder.getXPFactory(); if (!xpFactory->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) { SkDebugf("LCD Text will not draw correctly.\n"); } SkASSERT(!fCachedGeometryProcessor->hasVertexColor()); } else { // We're using per-vertex color. SkASSERT(fCachedGeometryProcessor->hasVertexColor()); } int nGlyphs = fCurrVertex / kVerticesPerGlyph; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(&pipelineBuilder, fCachedGeometryProcessor.get(), kTriangles_GrPrimitiveType, nGlyphs, kVerticesPerGlyph, kIndicesPerGlyph, &fVertexBounds); fDrawTarget->resetVertexSource(); fVertices = NULL; fTotalVertexCount -= fCurrVertex; fCurrVertex = 0; SkSafeSetNull(fCurrTexture); fVertexBounds.setLargestInverted(); } }
bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) { if (!stencil && !fRenderTarget->fStencilAttachment) { // No need to do any work since we currently don't have a stencil attachment and // we're not actually adding one. return true; } fRenderTarget->fStencilAttachment = stencil; if (!fRenderTarget->completeStencilAttachment()) { SkSafeSetNull(fRenderTarget->fStencilAttachment); return false; } return true; }
void GrDrawingManager::freeGpuResources() { for (int i = fOnFlushCBObjects.count() - 1; i >= 0; --i) { if (!fOnFlushCBObjects[i]->retainOnFreeGpuResources()) { // it's safe to just do this because we're iterating in reverse fOnFlushCBObjects.removeShuffle(i); } } // a path renderer may be holding onto resources delete fPathRendererChain; fPathRendererChain = nullptr; SkSafeSetNull(fSoftwarePathRenderer); }
void SKPBench::onPerCanvasPostDraw(SkCanvas* canvas) { // Draw the last set of tiles into the master canvas in case we're // saving the images for (int i = 0; i < fTileRects.count(); ++i) { SkAutoTUnref<SkImage> image(fSurfaces[i]->newImageSnapshot()); canvas->drawImage(image, SkIntToScalar(fTileRects[i].fLeft), SkIntToScalar(fTileRects[i].fTop)); SkSafeSetNull(fSurfaces[i]); } fSurfaces.rewind(); fTileRects.rewind(); }
void GrGpu::releaseResources() { fClipMaskManager.releaseResources(); while (NULL != fObjectList.head()) { fObjectList.head()->release(); } SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()); SkSafeSetNull(fQuadIndexBuffer); delete fVertexPool; fVertexPool = NULL; delete fIndexPool; fIndexPool = NULL; }
void GrGpu::releaseResources() { fClipMaskManager.releaseResources(); while (NULL != fResourceList.head()) { fResourceList.head()->release(); } SkASSERT(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid()); SkSafeSetNull(fQuadIndexBuffer); delete fVertexPool; fVertexPool = NULL; delete fIndexPool; fIndexPool = NULL; }
void GrDrawingManager::cleanup() { for (int i = 0; i < fOpLists.count(); ++i) { fOpLists[i]->makeClosed(); // no opList should receive a new command after this fOpLists[i]->clearTarget(); // We shouldn't need to do this, but it turns out some clients still hold onto opLists // after a cleanup fOpLists[i]->reset(); fOpLists[i]->unref(); } fOpLists.reset(); delete fPathRendererChain; fPathRendererChain = nullptr; SkSafeSetNull(fSoftwarePathRenderer); }
void GrDrawingManager::cleanup() { for (int i = 0; i < fOpLists.count(); ++i) { // no opList should receive a new command after this fOpLists[i]->makeClosed(*fContext->caps()); // We shouldn't need to do this, but it turns out some clients still hold onto opLists // after a cleanup. // MDB TODO: is this still true? if (!fOpLists[i]->unique()) { // TODO: Eventually this should be guaranteed unique. // https://bugs.chromium.org/p/skia/issues/detail?id=7111 fOpLists[i]->endFlush(); } } fOpLists.reset(); delete fPathRendererChain; fPathRendererChain = nullptr; SkSafeSetNull(fSoftwarePathRenderer); fOnFlushCBObjects.reset(); }
void GrBitmapTextContext::flushGlyphs() { if (NULL == fDrawTarget) { return; } GrDrawState* drawState = fDrawTarget->drawState(); GrDrawState::AutoRestoreEffects are(drawState); drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); if (fCurrVertex > 0) { // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); SkASSERT(fCurrTexture); GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); uint32_t textureUniqueID = fCurrTexture->getUniqueID(); if (textureUniqueID != fEffectTextureUniqueID) { fCachedEffect.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture, params)); fEffectTextureUniqueID = textureUniqueID; } // This effect could be stored with one of the cache objects (atlas?) int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex : kGlyphCoordsNoColorAttributeIndex; drawState->addCoverageEffect(fCachedEffect.get(), coordsIdx); SkASSERT(NULL != fStrike); switch (fStrike->getMaskFormat()) { // Color bitmap text case kARGB_GrMaskFormat: SkASSERT(!drawState->hasColorVertexAttribute()); drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); drawState->setColor(0xffffffff); break; // LCD text case kA888_GrMaskFormat: case kA565_GrMaskFormat: { if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { GrPrintf("LCD Text will not draw correctly.\n"); } SkASSERT(!drawState->hasColorVertexAttribute()); // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState->setColor(SkColorSetARGB(a, a, a, a)); // paintColor drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor())); drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); break; } // Grayscale/BW text case kA8_GrMaskFormat: // set back to normal in case we took LCD path previously. drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); // We're using per-vertex color. SkASSERT(drawState->hasColorVertexAttribute()); break; default: SkFAIL("Unexepected mask format."); } int nGlyphs = fCurrVertex / 4; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, nGlyphs, 4, 6, &fVertexBounds); fDrawTarget->resetVertexSource(); fVertices = NULL; fMaxVertices = 0; fCurrVertex = 0; fVertexBounds.setLargestInverted(); SkSafeSetNull(fCurrTexture); } }
void GrDistanceFieldTextContext::flush() { if (NULL == fDrawTarget) { return; } if (fCurrVertex > 0) { GrDrawState drawState; drawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget()); bool useColorVerts = !fUseLCDText; set_vertex_attributes(&drawState, useColorVerts); // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); // get our current color SkColor filteredColor; SkColorFilter* colorFilter = fSkPaint.getColorFilter(); if (colorFilter) { filteredColor = colorFilter->filterColor(fSkPaint.getColor()); } else { filteredColor = fSkPaint.getColor(); } this->setupCoverageEffect(filteredColor); // Effects could be stored with one of the cache objects (atlas?) drawState.setGeometryProcessor(fCachedGeometryProcessor.get()); // Set draw state if (fUseLCDText) { GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { SkDebugf("LCD Text will not draw correctly.\n"); } SkASSERT(!drawState.hasColorVertexAttribute()); // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState.setColor(SkColorSetARGB(a, a, a, a)); // paintColor drawState.setBlendConstant(colorNoPreMul); drawState.setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); } else { if (0xFF == GrColorUnpackA(fPaint.getColor())) { drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); } // set back to normal in case we took LCD path previously. drawState.setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); // We're using per-vertex color. SkASSERT(drawState.hasColorVertexAttribute()); } int nGlyphs = fCurrVertex / kVerticesPerGlyph; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(&drawState, kTriangles_GrPrimitiveType, nGlyphs, kVerticesPerGlyph, kIndicesPerGlyph, &fVertexBounds); fDrawTarget->resetVertexSource(); fVertices = NULL; fTotalVertexCount -= fCurrVertex; fCurrVertex = 0; SkSafeSetNull(fCurrTexture); fVertexBounds.setLargestInverted(); } }
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { SkSafeSetNull(fGammaTexture); }
void GrContext::DrawingMgr::abandon() { SkSafeSetNull(fDrawTarget); SkSafeSetNull(fDrawContext->fDrawTarget); SkSafeSetNull(fDrawContext); }
void SkPictureRecorder::reset() { SkSafeSetNull(fPictureRecord); SkSafeSetNull(fRecorder); SkDELETE(fRecord); fRecord = NULL; }
GrGpu::~GrGpu() { SkSafeSetNull(fQuadIndexBuffer); }
void GrAARectRenderer::reset() { SkSafeSetNull(fAAFillRectIndexBuffer); SkSafeSetNull(fAAMiterStrokeRectIndexBuffer); SkSafeSetNull(fAABevelStrokeRectIndexBuffer); }
void GrRenderTarget::onAbandon() { SkSafeSetNull(fStencilAttachment); INHERITED::onAbandon(); }
void GrRenderTarget::onRelease() { SkSafeSetNull(fStencilAttachment); INHERITED::onRelease(); }