void onDraw(SkCanvas* canvas) override { canvas->translate(20, 20); const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) { sk_sp<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture.get(), info)); if (image) { this->testImage(canvas, image.get()); } canvas->translate(120, 0); } }
void GrStyle::initPathEffect(sk_sp<SkPathEffect> pe) { SkASSERT(!fPathEffect); SkASSERT(SkPathEffect::kNone_DashType == fDashInfo.fType); SkASSERT(0 == fDashInfo.fIntervals.count()); if (!pe) { return; } SkPathEffect::DashInfo info; if (SkPathEffect::kDash_DashType == pe->asADash(&info)) { SkStrokeRec::Style recStyle = fStrokeRec.getStyle(); if (recStyle != SkStrokeRec::kFill_Style && recStyle != SkStrokeRec::kStrokeAndFill_Style) { fDashInfo.fType = SkPathEffect::kDash_DashType; fDashInfo.fIntervals.reset(info.fCount); fDashInfo.fPhase = info.fPhase; info.fIntervals = fDashInfo.fIntervals.get(); pe->asADash(&info); fPathEffect = std::move(pe); } } else { fPathEffect = std::move(pe); } }
std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrPaint&& paint, sk_sp<SkVertices> vertices, const SkMatrix& viewMatrix, GrAAType aaType, bool gammaCorrect, sk_sp<GrColorSpaceXform> colorSpaceXform, GrPrimitiveType* overridePrimType) { SkASSERT(vertices); GrPrimitiveType primType = overridePrimType ? *overridePrimType : SkVertexModeToGrPrimitiveType(vertices->mode()); return Helper::FactoryHelper<GrDrawVerticesOp>(std::move(paint), std::move(vertices), primType, aaType, gammaCorrect, std::move(colorSpaceXform), viewMatrix); }
sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy, sk_sp<SkColorSpace> colorSpace) { if (this->wasAbandoned() || !sProxy->asTextureProxy()) { return nullptr; } // SkSurface catches bad color space usage at creation. This check handles anything that slips // by, including internal usage. if (!SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) { SkDEBUGFAIL("Invalid config and colorspace combination"); return nullptr; } // GrTextureRenderTargets should always be using a GrRenderTargetContext SkASSERT(!sProxy->asRenderTargetProxy()); sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy())); return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy), std::move(colorSpace), fContext->contextPriv().getAuditTrail(), fSingleOwner)); }
sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target, SkTransferFunctionBehavior premulBehavior) const { SkColorSpaceTransferFn fn; if (!target || !target->isNumericalTransferFn(&fn)) { return nullptr; } // No need to create a new image if: // (1) The color spaces are equal. // (2) The color type is kAlpha8. if (SkColorSpace::Equals(this->colorSpace(), target.get()) || kAlpha_8_SkColorType == as_IB(this)->onImageInfo().colorType()) { return sk_ref_sp(const_cast<SkImage*>(this)); } SkColorType targetColorType = kN32_SkColorType; if (SkTransferFunctionBehavior::kRespect == premulBehavior && target->gammaIsLinear()) { targetColorType = kRGBA_F16_SkColorType; } // TODO: We might consider making this a deferred conversion? return as_IB(this)->onMakeColorSpace(std::move(target), targetColorType, premulBehavior); }
void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourceProvider, sk_sp<GrTextureProxy> proxy, GrSamplerParams::FilterMode filterMode, SkShader::TileMode tileXAndY, GrShaderFlags visibility) { // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy GrTexture* texture = proxy->instantiate(resourceProvider); SkASSERT(texture); fTexture.set(SkRef(texture), kRead_GrIOType); filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode()); fParams.reset(tileXAndY, filterMode); fVisibility = visibility; }
bool onQuery(Sample::Event* evt) override { if (Sample::TitleQ(*evt)) { Sample::TitleR(evt, fName); return true; } SkUnichar uni; if (Sample::CharQ(*evt, &uni)) { switch (uni) { case 'C': fDrawable->toggleUseColors(); return true; default: break; } } return this->INHERITED::onQuery(evt); }
void FuzzImageFilterDeserialize(sk_sp<SkData> bytes) { const int BitmapSize = 24; SkBitmap bitmap; bitmap.allocN32Pixels(BitmapSize, BitmapSize); SkCanvas canvas(bitmap); canvas.clear(0x00000000); auto flattenable = SkImageFilter::Deserialize(bytes->data(), bytes->size()); if (flattenable != nullptr) { // Let's see if using the filters can cause any trouble... SkPaint paint; paint.setImageFilter(flattenable); canvas.save(); canvas.clipRect(SkRect::MakeXYWH( 0, 0, SkIntToScalar(BitmapSize), SkIntToScalar(BitmapSize))); // This call shouldn't crash or cause ASAN to flag any memory issues // If nothing bad happens within this call, everything is fine canvas.drawBitmap(bitmap, 0, 0, &paint); canvas.restore(); } }
// Exercise the public API of SkSpecialSurface (e.g., getCanvas, newImageSnapshot) static void test_surface(const sk_sp<SkSpecialSurface>& surf, skiatest::Reporter* reporter, int offset) { const SkIRect surfSubset = TestingSpecialSurfaceAccess::Subset(surf.get()); REPORTER_ASSERT(reporter, offset == surfSubset.fLeft); REPORTER_ASSERT(reporter, offset == surfSubset.fTop); REPORTER_ASSERT(reporter, kSmallerSize == surfSubset.width()); REPORTER_ASSERT(reporter, kSmallerSize == surfSubset.height()); SkCanvas* canvas = surf->getCanvas(); SkASSERT_RELEASE(canvas); canvas->clear(SK_ColorRED); sk_sp<SkSpecialImage> img(surf->makeImageSnapshot()); REPORTER_ASSERT(reporter, img); const SkIRect imgSubset = img->subset(); REPORTER_ASSERT(reporter, surfSubset == imgSubset); // the canvas was invalidated by the newImageSnapshot call REPORTER_ASSERT(reporter, !surf->getCanvas()); }
sk_sp<sksg::PaintNode> AttachStroke(const Json::Value& jstroke, AttachContext* ctx, sk_sp<sksg::PaintNode> stroke_node) { SkASSERT(jstroke.isObject()); if (!stroke_node) return nullptr; stroke_node->setStyle(SkPaint::kStroke_Style); auto width_attached = BindProperty<ScalarValue>(jstroke["w"], &ctx->fAnimators, [stroke_node](const ScalarValue& w) { stroke_node->setStrokeWidth(w); }); if (!width_attached) return nullptr; stroke_node->setStrokeMiter(ParseDefault(jstroke["ml"], 4.0f)); static constexpr SkPaint::Join gJoins[] = { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join, }; stroke_node->setStrokeJoin(gJoins[SkTPin<int>(ParseDefault(jstroke["lj"], 1) - 1, 0, SK_ARRAY_COUNT(gJoins) - 1)]); static constexpr SkPaint::Cap gCaps[] = { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap, }; stroke_node->setStrokeCap(gCaps[SkTPin<int>(ParseDefault(jstroke["lc"], 1) - 1, 0, SK_ARRAY_COUNT(gCaps) - 1)]); return stroke_node; }
void findDefaultStyleSet() { SkASSERT(!fStyleSets.empty()); static const char* defaultNames[] = { "sans-serif" }; for (const char* defaultName : defaultNames) { fDefaultStyleSet.reset(this->onMatchFamily(defaultName)); if (fDefaultStyleSet) { break; } } if (nullptr == fDefaultStyleSet) { fDefaultStyleSet = fStyleSets[0]; } SkASSERT(fDefaultStyleSet); }
sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithProc(const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable, void* addr, SkMallocPixelRef::ReleaseProc proc, void* context) { if (!is_valid(info, ctable.get())) { if (proc) { proc(addr, context); } return nullptr; } return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes, std::move(ctable), proc, context)); }
void onDraw(SkCanvas* canvas) override { if (nullptr == fBitmap.pixelRef()) { fImage = make_image(canvas, &fCenter); image_to_bitmap(fImage.get(), &fBitmap); } // amount of bm that should not be stretched (unless we have to) const SkScalar fixed = SkIntToScalar(fBitmap.width() - fCenter.width()); const SkTSize<SkScalar> size[] = { { fixed * 4 / 5, fixed * 4 / 5 }, // shrink in both axes { fixed * 4 / 5, fixed * 4 }, // shrink in X { fixed * 4, fixed * 4 / 5 }, // shrink in Y { fixed * 4, fixed * 4 } }; canvas->drawBitmap(fBitmap, 10, 10, nullptr); SkScalar x = SkIntToScalar(100); SkScalar y = SkIntToScalar(100); SkPaint paint; for (int filter = 0; filter < 2; filter++) { paint.setFilterQuality(filter == 0 ? kLow_SkFilterQuality : kNone_SkFilterQuality); canvas->translate(0, filter * SkIntToScalar(400)); for (int iy = 0; iy < 2; ++iy) { for (int ix = 0; ix < 2; ++ix) { int i = ix * 2 + iy; SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed, size[i].width(), size[i].height()); canvas->drawBitmapNine(fBitmap, fCenter, r, &paint); canvas->drawImageNine(fImage.get(), fCenter, r.makeOffset(360, 0), &paint); } } } }
/* * Modulo internal errors, this should always succeed *if* the matrix is downscaling * (in this case, we have the inverse, so it succeeds if fInvMatrix is upscaling) */ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider& provider) { SkASSERT(fQuality <= kMedium_SkFilterQuality); if (fQuality != kMedium_SkFilterQuality) { return false; } // Our default return state is to downgrade the request to Low, w/ or w/o setting fBitmap // to a valid bitmap. fQuality = kLow_SkFilterQuality; SkSize invScaleSize; if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) { return false; } SkDestinationSurfaceColorMode colorMode = provider.dstColorSpace() ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware : SkDestinationSurfaceColorMode::kLegacy; if (invScaleSize.width() > SK_Scalar1 || invScaleSize.height() > SK_Scalar1) { fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc(), colorMode)); if (nullptr == fCurrMip.get()) { SkBitmap orig; if (!provider.asBitmap(&orig)) { return false; } fCurrMip.reset(SkMipMapCache::AddAndRef(orig, colorMode)); if (nullptr == fCurrMip.get()) { return false; } } // diagnostic for a crasher... SkASSERT_RELEASE(fCurrMip->data()); const SkSize scale = SkSize::Make(SkScalarInvert(invScaleSize.width()), SkScalarInvert(invScaleSize.height())); SkMipMap::Level level; if (fCurrMip->extractLevel(scale, &level)) { const SkSize& invScaleFixup = level.fScale; fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height()); // todo: if we could wrap the fCurrMip in a pixelref, then we could just install // that here, and not need to explicitly track it ourselves. return fResultBitmap.installPixels(level.fPixmap); } else { // failed to extract, so release the mipmap fCurrMip.reset(nullptr); } } return false; }
sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context, sk_sp<GrTextureProxy> inputProxy, const CopyParams& copyParams, bool dstWillRequireMipMaps) { SkASSERT(context); const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight); GrMipMapped mipMapped = dstWillRequireMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo; SkRect localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height()); bool needsDomain = false; bool resizing = false; if (copyParams.fFilter != GrSamplerState::Filter::kNearest) { bool resizing = localRect.width() != dstRect.width() || localRect.height() != dstRect.height(); needsDomain = resizing && !GrProxyProvider::IsFunctionallyExact(inputProxy.get()); } if (copyParams.fFilter == GrSamplerState::Filter::kNearest && !needsDomain && !resizing && dstWillRequireMipMaps) { sk_sp<GrTextureProxy> proxy = GrCopyBaseMipMapToTextureProxy(context, inputProxy.get()); if (proxy) { return proxy; } } sk_sp<GrRenderTargetContext> copyRTC = context->contextPriv().makeDeferredRenderTargetContextWithFallback( SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(), nullptr, 1, mipMapped, inputProxy->origin()); if (!copyRTC) { return nullptr; } GrPaint paint; if (needsDomain) { const SkRect domain = localRect.makeInset(0.5f, 0.5f); // This would cause us to read values from outside the subset. Surely, the caller knows // better! SkASSERT(copyParams.fFilter != GrSamplerState::Filter::kMipMap); paint.addColorFragmentProcessor( GrTextureDomainEffect::Make(std::move(inputProxy), SkMatrix::I(), domain, GrTextureDomain::kClamp_Mode, copyParams.fFilter)); } else { GrSamplerState samplerState(GrSamplerState::WrapMode::kClamp, copyParams.fFilter); paint.addColorTextureProcessor(std::move(inputProxy), SkMatrix::I(), samplerState); } paint.setPorterDuffXPFactory(SkBlendMode::kSrc); copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect, localRect); return copyRTC->asTextureProxyRef(); }
SkSpecialSurface_Gpu(GrContext* context, sk_sp<GrRenderTargetContext> renderTargetContext, int width, int height, const SkIRect& subset) : INHERITED(subset, &renderTargetContext->surfaceProps()) , fRenderTargetContext(std::move(renderTargetContext)) { sk_sp<SkBaseDevice> device(SkGpuDevice::Make(context, fRenderTargetContext, width, height, SkGpuDevice::kUninit_InitContents)); if (!device) { return; } fCanvas.reset(new SkCanvas(device)); fCanvas->clipRect(SkRect::Make(subset)); #ifdef SK_IS_BOT fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness #endif }
void gradCheck(skiatest::Reporter* reporter, const sk_sp<SkShader>& shader, SkShader::GradientInfo* info, SkShader::GradientType gt) const { SkAutoTMalloc<SkColor> colorStorage(fColorCount); SkAutoTMalloc<SkScalar> posStorage(fColorCount); info->fColorCount = fColorCount; info->fColors = colorStorage; info->fColorOffsets = posStorage.get(); REPORTER_ASSERT(reporter, shader->asAGradient(info) == gt); REPORTER_ASSERT(reporter, info->fColorCount == fColorCount); REPORTER_ASSERT(reporter, !memcmp(info->fColors, fColors, fColorCount * sizeof(SkColor))); REPORTER_ASSERT(reporter, !memcmp(info->fColorOffsets, fPos, fColorCount * sizeof(SkScalar))); REPORTER_ASSERT(reporter, fTileMode == (SkTileMode)info->fTileMode); }
void onDraw(SkCanvas* canvas) override { SkRSXform xform[N]; SkColor colors[N]; for (int i = 0; i < N; ++i) { fRec[i].advance(fBounds); xform[i] = fRec[i].asRSXform(); if (fUseColors) { colors[i] = SkColorSetARGB((int)(fRec[i].fAlpha * 0xFF), 0xFF, 0xFF, 0xFF); } } SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); const SkRect cull = this->getBounds(); const SkColor* colorsPtr = fUseColors ? colors : nullptr; fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, &paint); }
// If either id is different or the clip or the matrix are different the // cached image won't be found. Even if it is caching the same bitmap. static void test_dont_find_if_diff_key(skiatest::Reporter* reporter, const sk_sp<SkSpecialImage>& image, const sk_sp<SkSpecialImage>& subset) { static const size_t kCacheSize = 1000000; SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kCacheSize)); SkIRect clip1 = SkIRect::MakeWH(100, 100); SkIRect clip2 = SkIRect::MakeWH(200, 200); SkImageFilter::Cache::Key key0(0, SkMatrix::I(), clip1, image->uniqueID(), image->subset()); SkImageFilter::Cache::Key key1(1, SkMatrix::I(), clip1, image->uniqueID(), image->subset()); SkImageFilter::Cache::Key key2(0, SkMatrix::MakeTrans(5, 5), clip1, image->uniqueID(), image->subset()); SkImageFilter::Cache::Key key3(0, SkMatrix::I(), clip2, image->uniqueID(), image->subset()); SkImageFilter::Cache::Key key4(0, SkMatrix::I(), clip1, subset->uniqueID(), subset->subset()); SkIPoint offset = SkIPoint::Make(3, 4); cache->set(key0, image.get(), offset); SkIPoint foundOffset; REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset)); REPORTER_ASSERT(reporter, !cache->get(key2, &foundOffset)); REPORTER_ASSERT(reporter, !cache->get(key3, &foundOffset)); REPORTER_ASSERT(reporter, !cache->get(key4, &foundOffset)); }
std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrRecordingContext* context, GrPaint&& paint, sk_sp<SkVertices> vertices, const SkVertices::Bone bones[], int boneCount, const SkMatrix& viewMatrix, GrAAType aaType, sk_sp<GrColorSpaceXform> colorSpaceXform, GrPrimitiveType* overridePrimType) { SkASSERT(vertices); GrPrimitiveType primType = overridePrimType ? *overridePrimType : SkVertexModeToGrPrimitiveType(vertices->mode()); return GrSimpleMeshDrawOpHelper::FactoryHelper<DrawVerticesOp>(context, std::move(paint), std::move(vertices), bones, boneCount, primType, aaType, std::move(colorSpaceXform), viewMatrix); }
sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext* context, const GrBackendTexture& tex, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props) { if (!context) { return nullptr; } sampleCnt = SkTMax(1, sampleCnt); GrBackendTexture texCopy = tex; if (!validate_backend_texture(context, texCopy, &texCopy.fConfig, sampleCnt, colorType, colorSpace, true)) { return nullptr; } if (!context) { return nullptr; } if (!SkSurface_Gpu::Valid(context, texCopy.config(), colorSpace.get())) { return nullptr; } sampleCnt = SkTMax(1, sampleCnt); sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeBackendTextureRenderTargetContext( texCopy, origin, sampleCnt, std::move(colorSpace), props)); if (!rtc) { return nullptr; } sk_sp<SkGpuDevice> device(SkGpuDevice::Make(context, std::move(rtc), texCopy.width(), texCopy.height(), SkGpuDevice::kUninit_InitContents)); if (!device) { return nullptr; } return sk_make_sp<SkSurface_Gpu>(std::move(device)); }
sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t), const SkImageInfo& info, size_t requestedRowBytes, sk_sp<SkColorTable> ctable) { if (!is_valid(info, ctable.get())) { return nullptr; } // only want to permit 31bits of rowBytes int64_t minRB = (int64_t)info.minRowBytes64(); if (minRB < 0 || !sk_64_isS32(minRB)) { return nullptr; // allocation will be too large } if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { return nullptr; // cannot meet requested rowbytes } int32_t rowBytes; if (requestedRowBytes) { rowBytes = SkToS32(requestedRowBytes); } else { rowBytes = minRB; } int64_t bigSize = (int64_t)info.height() * rowBytes; if (!sk_64_isS32(bigSize)) { return nullptr; } size_t size = sk_64_asS32(bigSize); SkASSERT(size >= info.getSafeSize(rowBytes)); void* addr = alloc(size); if (nullptr == addr) { return nullptr; } return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes, std::move(ctable), sk_free_releaseproc, nullptr)); }
void SkInternalAtlasTextTarget::addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) { SkASSERT(clip.quickContains(SkRect::MakeIWH(fWidth, fHeight))); // The SkAtlasTextRenderer currently only handles grayscale SDF glyphs. if (op->maskType() != GrAtlasTextOp::kGrayscaleDistanceField_MaskType) { return; } const GrCaps& caps = *this->context()->internal().grContext()->contextPriv().caps(); op->finalizeForTextTarget(fColor, caps); int n = SkTMin(kMaxBatchLookBack, fOps.count()); for (int i = 0; i < n; ++i) { GrAtlasTextOp* other = fOps.fromBack(i).get(); if (other->combineIfPossible(op.get(), caps) == GrOp::CombineResult::kMerged) { fOpMemoryPool->release(std::move(op)); return; } if (GrRectsOverlap(op->bounds(), other->bounds())) { break; } } op->visitProxies([](GrSurfaceProxy*) {}); fOps.emplace_back(std::move(op)); }
sk_sp<GrTextureProxy> GrMakeCachedImageProxy(GrProxyProvider* proxyProvider, sk_sp<SkImage> srcImage, SkBackingFit fit) { sk_sp<GrTextureProxy> proxy; GrUniqueKey originalKey; create_unique_key_for_image(srcImage.get(), &originalKey); if (originalKey.isValid()) { proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin); } if (!proxy) { proxy = proxyProvider->createTextureProxy(std::move(srcImage), kNone_GrSurfaceFlags, kTopLeft_GrSurfaceOrigin, 1, SkBudgeted::kYes, fit); if (proxy && originalKey.isValid()) { proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get()); } } return proxy; }
sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext* context, const GrBackendRenderTarget& rt, GrSurfaceOrigin origin, SkColorType colorType, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props) { if (!context) { return nullptr; } GrBackendRenderTarget rtCopy = rt; if (!validate_backend_render_target(context, rtCopy, &rtCopy.fConfig, colorType, colorSpace)) { return nullptr; } if (!SkSurface_Gpu::Valid(context, rtCopy.config(), colorSpace.get())) { return nullptr; } if (!context) { return nullptr; } sk_sp<GrRenderTargetContext> rtc( context->contextPriv().makeBackendRenderTargetRenderTargetContext( rtCopy, origin, std::move(colorSpace), props)); if (!rtc) { return nullptr; } sk_sp<SkGpuDevice> device(SkGpuDevice::Make(context, std::move(rtc), rtCopy.width(), rtCopy.height(), SkGpuDevice::kUninit_InitContents)); if (!device) { return nullptr; } return sk_make_sp<SkSurface_Gpu>(std::move(device)); }
sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context, sk_sp<GrFragmentProcessor> fp, const SkIRect& bounds) { GrPaint paint; paint.addColorFragmentProcessor(fp.get()); paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit, bounds.width(), bounds.height(), kRGBA_8888_GrPixelConfig)); if (!drawContext) { return nullptr; } SkRect srcRect = SkRect::Make(bounds); SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); GrClip clip(dstRect); drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()), kNeedNewImageUniqueID_SpecialImage, drawContext->asTexture()); }
// Test various cases when two proxies do not have overlapping intervals. // This mainly acts as a test of the ResourceAllocator's free pool. static void non_overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider, sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2, bool expectedResult) { GrResourceAllocator alloc(resourceProvider); alloc.addInterval(p1.get(), 0, 2); alloc.addInterval(p2.get(), 3, 5); alloc.markEndOfOpList(0); int startIndex, stopIndex; GrResourceAllocator::AssignError error; alloc.assign(&startIndex, &stopIndex, &error); REPORTER_ASSERT(reporter, GrResourceAllocator::AssignError::kNoError == error); REPORTER_ASSERT(reporter, p1->priv().peekSurface()); REPORTER_ASSERT(reporter, p2->priv().peekSurface()); bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID(); REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch); }
// Test purging when the max cache size is exceeded static void test_internal_purge(skiatest::Reporter* reporter, const sk_sp<SkSpecialImage>& image) { SkASSERT(image->getSize()); const size_t kCacheSize = image->getSize() + 10; SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kCacheSize)); SkIRect clip = SkIRect::MakeWH(100, 100); SkImageFilter::Cache::Key key1(0, SkMatrix::I(), clip, image->uniqueID(), image->subset()); SkImageFilter::Cache::Key key2(1, SkMatrix::I(), clip, image->uniqueID(), image->subset()); SkIPoint offset = SkIPoint::Make(3, 4); cache->set(key1, image.get(), offset); SkIPoint foundOffset; REPORTER_ASSERT(reporter, cache->get(key1, &foundOffset)); // This should knock the first one out of the cache cache->set(key2, image.get(), offset); REPORTER_ASSERT(reporter, cache->get(key2, &foundOffset)); REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset)); }
int main() { const DrawOptions options = GetDrawOptions(); if (options.source) { sk_sp<SkData> data(SkData::NewFromFileName(options.source)); if (!data) { perror(options.source); return 1; } else { image = SkImage::MakeFromEncoded(std::move(data)); if (!image) { perror("Unable to decode the source image."); return 1; } SkAssertResult(image->asLegacyBitmap( &source, SkImage::kRO_LegacyBitmapMode)); } } sk_sp<SkData> rasterData, gpuData, pdfData, skpData; if (options.raster) { auto rasterSurface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(options.size)); srand(0); draw(rasterSurface->getCanvas()); rasterData.reset(encode_snapshot(rasterSurface)); } if (options.gpu) { auto grContext = create_grcontext(); if (!grContext) { fputs("Unable to get GrContext.\n", stderr); } else { auto surface = SkSurface::MakeRenderTarget( grContext.get(), SkBudgeted::kNo, SkImageInfo::MakeN32Premul(options.size)); if (!surface) { fputs("Unable to get render surface.\n", stderr); exit(1); } srand(0); draw(surface->getCanvas()); gpuData.reset(encode_snapshot(surface)); } } if (options.pdf) { SkDynamicMemoryWStream pdfStream; sk_sp<SkDocument> document(SkDocument::MakePDF(&pdfStream)); srand(0); draw(document->beginPage(options.size.width(), options.size.height())); document->close(); pdfData.reset(pdfStream.copyToData()); } if (options.skp) { SkSize size; size = options.size; SkPictureRecorder recorder; srand(0); draw(recorder.beginRecording(size.width(), size.height())); auto picture = recorder.finishRecordingAsPicture(); SkDynamicMemoryWStream skpStream; picture->serialize(&skpStream); skpData.reset(skpStream.copyToData()); } printf("{\n"); dump_output(rasterData, "Raster", !gpuData && !pdfData && !skpData); dump_output(gpuData, "Gpu", !pdfData && !skpData); dump_output(pdfData, "Pdf", !skpData); dump_output(skpData, "Skp"); printf("}\n"); return 0; }
SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt) : SkTypeface(proxy->fontStyle(), false) , fProxy(std::move(proxy)) , fPaint(paint) , fFakeIt(fakeIt) {}