void draw(SkCanvas* canvas) { canvas->drawBitmap(source, 0, 0); SkPaint bgPaint; bgPaint.setColor(0xafffffff); canvas->drawRect({20, 50, 80, 70}, bgPaint); uint8_t green = SkColorGetG(source.getColor(57, 192)); canvas->drawString(std::to_string(green).c_str(), 40, 65, SkPaint()); canvas->drawLine(80, 70, 57, 192, SkPaint()); }
void draw(SkCanvas* canvas) { SkFont blobFont; blobFont.setSize(24); sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont); char storage[2048]; size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage)); sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs()); canvas->drawTextBlob(copy, 20, 20, SkPaint()); std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used); canvas->drawString(usage.c_str(), 20, 40, SkPaint()); }
DEF_TEST(RecordOpts_NoopDraw, r) { SkRecord record; SkRecorder recorder(&record, W, H); recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint()); recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint()); recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint()); record.replace<SkRecords::NoOp>(1); // NoOps should be allowed. SkRecordNoopSaveRestores(&record); REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record)); }
void draw(SkCanvas* canvas) { SkRRect rrect1 = SkRRect::MakeRectXY({10, 20, 60, 220}, 50, 100); SkRRect rrect2 = SkRRect::MakeRectXY(rrect1.rect(), 50, 50); SkRRect rrect3 = SkRRect::MakeOval(rrect1.rect()); canvas->drawRRect(rrect1, SkPaint()); std::string str = "rrect1 " + std::string(rrect1 == rrect2 ? "=" : "!") + "= rrect2"; canvas->drawString(str.c_str(), 10, 240, SkPaint()); canvas->translate(70, 0); canvas->drawRRect(rrect2, SkPaint()); canvas->translate(70, 0); canvas->drawRRect(rrect3, SkPaint()); str = "rrect2 " + std::string(rrect2 == rrect3 ? "=" : "!") + "= rrect3"; canvas->drawString(str.c_str(), -20, 240, SkPaint()); }
// Test drawing text at some unusual coordinates. // We measure success by not crashing or asserting. DEF_TEST(DrawText_weirdCoordinates, r) { auto surface = SkSurface::MakeRasterN32Premul(10,10); auto canvas = surface->getCanvas(); SkScalar oddballs[] = { 0.0f, (float)INFINITY, (float)NAN, 34359738368.0f }; for (auto x : oddballs) { canvas->drawString("a", +x, 0.0f, SkPaint()); canvas->drawString("a", -x, 0.0f, SkPaint()); } for (auto y : oddballs) { canvas->drawString("a", 0.0f, +y, SkPaint()); canvas->drawString("a", 0.0f, -y, SkPaint()); } }
// A regression test for crbug.com/415468 and https://bug.skia.org/2957 . // // This also now serves as a regression test for crbug.com/418417. We used to adjust the // bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture. // (We were applying the saveLayer paint to the bounds after restore, which makes no sense.) DEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) { SkRecord record; SkRecorder recorder(&record, 50, 50); // We draw a rectangle with a long drop shadow. We used to not update the clip // bounds based on SaveLayer paints, so the drop shadow could be cut off. SkPaint paint; paint.setImageFilter(SkDropShadowImageFilter::Make( 20, 0, 0, 0, SK_ColorBLACK, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr)); recorder.saveLayer(nullptr, &paint); recorder.clipRect(SkRect::MakeWH(20, 40)); recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint()); recorder.restore(); // Under the original bug, the right edge value of the drawRect would be 20 less than asserted // here because we intersected it with a clip that had not been adjusted for the drop shadow. // // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too. // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50). SkAutoTMalloc<SkRect> bounds(record.count()); SkRecordFillBounds(SkRect::MakeWH(50, 50), record, bounds); REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0, 0, 50, 50))); REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 0, 50, 50))); REPORTER_ASSERT(r, sloppy_rect_eq(bounds[2], SkRect::MakeLTRB(0, 0, 40, 40))); REPORTER_ASSERT(r, sloppy_rect_eq(bounds[3], SkRect::MakeLTRB(0, 0, 50, 50))); }
/* Hit a few SkPicture::Analysis cases not handled elsewhere. */ static void test_analysis(skiatest::Reporter* reporter) { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(100, 100); { canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ()); } SkAutoTUnref<SkPicture> picture(recorder.endRecording()); REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps()); canvas = recorder.beginRecording(100, 100); { SkPaint paint; // CreateBitmapShader is too smart for us; an empty (or 1x1) bitmap shader // gets optimized into a non-bitmap form, so we create a 2x2 bitmap here. SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2)); bitmap.eraseColor(SK_ColorBLUE); *(bitmap.getAddr32(0, 0)) = SK_ColorGREEN; SkShader* shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); paint.setShader(shader)->unref(); REPORTER_ASSERT(reporter, shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType); canvas->drawRect(SkRect::MakeWH(10, 10), paint); } picture.reset(recorder.endRecording()); REPORTER_ASSERT(reporter, picture->willPlayBackBitmaps()); }
/* Hit a few SkPicture::Analysis cases not handled elsewhere. */ static void test_analysis(skiatest::Reporter* reporter) { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(100, 100); { canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ()); } sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps()); canvas = recorder.beginRecording(100, 100); { SkPaint paint; // CreateBitmapShader is too smart for us; an empty (or 1x1) bitmap shader // gets optimized into a non-bitmap form, so we create a 2x2 bitmap here. SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2)); bitmap.eraseColor(SK_ColorBLUE); *(bitmap.getAddr32(0, 0)) = SK_ColorGREEN; paint.setShader(SkShader::MakeBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)); REPORTER_ASSERT(reporter, paint.getShader()->isABitmap()); canvas->drawRect(SkRect::MakeWH(10, 10), paint); } REPORTER_ASSERT(reporter, recorder.finishRecordingAsPicture()->willPlayBackBitmaps()); }
// Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureMipMapInvalidationTest, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); if (!context->priv().caps()->mipMapSupport()) { return; } auto isMipped = [] (SkSurface* surf) { const GrTexture* texture = surf->makeImageSnapshot()->getTexture(); return GrMipMapped::kYes == texture->texturePriv().mipMapped(); }; auto mipsAreDirty = [] (SkSurface* surf) { return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty(); }; auto info = SkImageInfo::MakeN32Premul(256, 256); for (auto allocateMips : {false, true}) { auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr, allocateMips); auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info); // Draw something just in case we ever had a solid color optimization surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint()); surf1->flush(); // No mipmaps initially REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips); // Painting with downscale and medium filter quality should result in mipmap creation // Flush the context rather than the canvas as flushing the canvas triggers MIP level // generation. SkPaint paint; paint.setFilterQuality(kMedium_SkFilterQuality); surf2->getCanvas()->scale(0.2f, 0.2f); surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint); context->flush(); REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips); REPORTER_ASSERT(reporter, !allocateMips || !mipsAreDirty(surf1.get())); // Changing the contents of the surface should invalidate the mipmap, but not de-allocate surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint()); context->flush(); REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips); REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get())); } }
void draw(SkCanvas* canvas) { const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x", "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16Norm", "RGBA_F16" }; SkColorType colorType = image->colorType(); canvas->drawImage(image, 16, 0); canvas->drawString(colors[(int) colorType], 20, image->height() + 20, SkFont(), SkPaint()); }
static void draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar y) { const size_t len = strlen(text); SkAutoTMalloc<SkScalar> xpos(len); for (size_t i = 0; i < len; i++) { xpos[i] = (SkScalar)i; } canvas->drawPosTextH(text, len, xpos, y, SkPaint()); }
DEF_SIMPLE_GM_BG(overdraw_canvas, canvas, WIDTH, HEIGHT, SK_ColorWHITE) { // Set up the overdraw canvas. SkImageInfo offscreenInfo = SkImageInfo::MakeA8(WIDTH, HEIGHT); sk_sp<SkSurface> offscreen = SkSurface::MakeRaster(offscreenInfo); auto c = offscreen->getCanvas(); SkOverdrawCanvas overdrawCanvas(c); overdrawCanvas.drawRect(SkRect::MakeLTRB(10, 10, 200, 200), SkPaint()); overdrawCanvas.drawRect(SkRect::MakeLTRB(20, 20, 190, 190), SkPaint()); overdrawCanvas.drawRect(SkRect::MakeLTRB(30, 30, 180, 180), SkPaint()); overdrawCanvas.drawRect(SkRect::MakeLTRB(40, 40, 170, 170), SkPaint()); overdrawCanvas.drawRect(SkRect::MakeLTRB(50, 50, 160, 160), SkPaint()); overdrawCanvas.drawRect(SkRect::MakeLTRB(60, 60, 150, 150), SkPaint()); char text[] = "Ae_p"; overdrawCanvas.drawSimpleText(text, 4, SkTextEncoding::kUTF8, 300, 300, SkFont(), SkPaint()); sk_sp<SkImage> counts = offscreen->makeImageSnapshot(); // Draw overdraw colors to the canvas. The color filter will convert counts to colors. SkPaint paint; paint.setColorFilter(SkOverdrawColorFilter::Make(kOverdrawColors)); canvas->drawImage(counts.get(), 0.0f, 0.0f, &paint); canvas->drawString("This is some text:", 180, 300, SkFont(), SkPaint()); }
// This test used to assert without the fix submitted for // http://code.google.com/p/skia/issues/detail?id=1083. // SKP files might have invalid glyph ids. This test ensures they are ignored, // and there is no assert on input data in Debug mode. static void test_issue1083() { SkDynamicMemoryWStream outStream; auto doc = SkPDF::MakeDocument(&outStream); SkCanvas* canvas = doc->beginPage(100.0f, 100.0f); uint16_t glyphID = 65000; canvas->drawSimpleText(&glyphID, 2, SkTextEncoding::kGlyphID, 0, 0, SkFont(), SkPaint()); doc->close(); }
DEF_TEST(Recorder, r) { SkRecord record; SkRecorder recorder(&record, 1920, 1080); recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint()); Tally tally; tally.apply(record); REPORTER_ASSERT(r, 1 == tally.count<SkRecords::DrawRect>()); }
bool SkSave::draw(SkAnimateMaker& maker) { maker.fCanvas->save(); SkPaint* save = maker.fPaint; SkPaint local = SkPaint(*maker.fPaint); maker.fPaint = &local; bool result = INHERITED::draw(maker); maker.fPaint = save; maker.fCanvas->restore(); return result; }
// Test out the layer replacement functionality with and w/o a BBH void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) { sk_sp<SkPicture> pic; { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); SkPaint paint; canvas->saveLayer(nullptr, &paint); canvas->clear(SK_ColorRED); canvas->restore(); canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)), SkPaint()); pic = recorder.finishRecordingAsPicture(); } SkAutoTUnref<GrTexture> texture; SkPaint paint; GrLayerCache* layerCache = context->getLayerCache(); if (doReplace) { int key[1] = { 0 }; GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, SkIRect::MakeWH(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight), SkMatrix::I(), key, 1, &paint); GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidth; desc.fHeight = kHeight; desc.fSampleCnt = 0; // Giving the texture some initial data so the Gpu (specifically vulkan) does not complain // when reading from an uninitialized texture. SkAutoTMalloc<uint32_t> srcBuffer(kWidth*kHeight); memset(srcBuffer.get(), 0, kWidth*kHeight*sizeof(uint32_t)); texture.reset(context->textureProvider()->createTexture( desc, SkBudgeted::kNo, srcBuffer.get(), 0)); layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); } SkRecord rerecord; SkRecorder canvas(&rerecord, kWidth, kHeight); GrRecordReplaceDraw(pic.get(), &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/); int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); if (doReplace) { REPORTER_ASSERT(r, 0 == numLayers); } else { REPORTER_ASSERT(r, 1 == numLayers); } }
DEF_TEST(SkPDF_document_skbug_4734, r) { REQUIRE_PDF_DOCUMENT(SkPDF_document_skbug_4734, r); SkDynamicMemoryWStream stream; auto doc = SkPDF::MakeDocument(&stream); SkCanvas* canvas = doc->beginPage(64, 64); canvas->scale(10000.0f, 10000.0f); canvas->translate(20.0f, 10.0f); canvas->rotate(30.0f); const char text[] = "HELLO"; canvas->drawString(text, 0, 0, SkFont(), SkPaint()); }
// When the canvas clip covers the full picture, we don't need to call the BBH. DEF_TEST(Picture_SkipBBH, r) { SkRect bound = SkRect::MakeWH(320, 240); CountingBBH bbh(bound); SpoonFedBBHFactory factory(&bbh); SkPictureRecorder recorder; SkCanvas* c = recorder.beginRecording(bound, &factory); // Record a few ops so we don't hit a small- or empty- picture optimization. c->drawRect(bound, SkPaint()); c->drawRect(bound, SkPaint()); sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); SkCanvas big(640, 480), small(300, 200); picture->playback(&big); REPORTER_ASSERT(r, bbh.searchCalls == 0); picture->playback(&small); REPORTER_ASSERT(r, bbh.searchCalls == 1); }
void draw(SkCanvas* canvas) { SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ? '=' : '!'); const int w = 37; const int h = 1000; auto surf = SkSurface::MakeNull(w, h); auto nullCanvas = surf->getCanvas(); nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ? '=' : '!'); }
DEF_TEST(document_skbug_4734, r) { REQUIRE_PDF_DOCUMENT(document_skbug_4734, r); SkDynamicMemoryWStream stream; SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&stream)); SkCanvas* canvas = doc->beginPage(64, 64); canvas->scale(10000.0f, 10000.0f); canvas->translate(20.0f, 10.0f); canvas->rotate(30.0f); const char text[] = "HELLO"; canvas->drawText(text, strlen(text), 0, 0, SkPaint()); }
void draw(SkCanvas* canvas) { SkRRect rrect = SkRRect::MakeEmpty(); SkRRect rrect2(rrect); rrect2.inset(-20, -20); SkPaint p; p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(10); std::string str("Type "); str += SkRRect::kEmpty_Type == rrect2.type() ? "=" : "!"; str += "= SkRRect::kEmpty_Type"; canvas->drawString(str.c_str(), 20, 80, SkPaint()); canvas->drawRRect(rrect2, p); }
void draw(SkCanvas* canvas) { canvas->drawBitmap(source, 0, 0); SkPaint bgPaint; bgPaint.setColor(0xafffffff); canvas->drawRect({20, 30, 110, 90}, bgPaint); SkScalar hsv[3]; SkColor c = source.getColor(226, 128); SkRGBToHSV(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), hsv); canvas->drawString(("h: " + std::to_string(hsv[0]).substr(0, 6)).c_str(), 27, 45, SkPaint()); canvas->drawString(("s: " + std::to_string(hsv[1]).substr(0, 6)).c_str(), 27, 65, SkPaint()); canvas->drawString(("v: " + std::to_string(hsv[2]).substr(0, 6)).c_str(), 27, 85, SkPaint()); canvas->drawLine(110, 90, 226, 128, SkPaint()); }
bool SkDisplayMovie::draw(SkAnimateMaker& maker) { if (fDecodedSuccessfully == false) return false; if (fLoaded == false) enable(maker); maker.fCanvas->save(); SkPaint local = SkPaint(*maker.fPaint); bool result = fMovie.draw(maker.fCanvas, &local, maker.fDisplayList.getTime()) != SkAnimator::kNotDifferent; maker.fDisplayList.fInvalBounds.join(fMovie.fMaker->fDisplayList.fInvalBounds); maker.fCanvas->restore(); return result; }
PassRefPtr<SkImage> SVGImage::imageForCurrentFrameForContainer(const KURL& url) { if (!m_page) return nullptr; SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(width(), height()); drawForContainer(canvas, SkPaint(), FloatSize(size()), 1, rect(), rect(), url); RefPtr<SkPicture> picture = adoptRef(recorder.endRecording()); return adoptRef( SkImage::NewFromPicture(picture.get(), SkISize::Make(width(), height()), nullptr, nullptr)); }
void FuzzPathDeserialize(SkReadBuffer& buf) { SkPath path; buf.readPath(&path); if (!buf.isValid()) { return; } auto s = SkSurface::MakeRasterN32Premul(128, 128); if (!s) { // May return nullptr in memory-constrained fuzzing environments return; } s->getCanvas()->drawPath(path, SkPaint()); }
// Test out the layer replacement functionality with and w/o a BBH void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) { SkAutoTUnref<const SkPicture> pic; { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); SkPaint paint; canvas->saveLayer(nullptr, &paint); canvas->clear(SK_ColorRED); canvas->restore(); canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)), SkPaint()); pic.reset(recorder.endRecording()); } SkAutoTUnref<GrTexture> texture; SkPaint paint; GrLayerCache* layerCache = context->getLayerCache(); if (doReplace) { int key[1] = { 0 }; GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, SkIRect::MakeWH(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight), SkMatrix::I(), key, 1, &paint); GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidth; desc.fHeight = kHeight; desc.fSampleCnt = 0; texture.reset(context->textureProvider()->createTexture( desc, SkBudgeted::kNo, nullptr, 0)); layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); } SkRecord rerecord; SkRecorder canvas(&rerecord, kWidth, kHeight); GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/); int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); if (doReplace) { REPORTER_ASSERT(r, 0 == numLayers); } else { REPORTER_ASSERT(r, 1 == numLayers); } }
// A regression test for crbug.com/409110. DEF_TEST(RecordDraw_TextBounds, r) { SkRecord record; SkRecorder recorder(&record, W, H); // Two Chinese characters in UTF-8. const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' }; const size_t bytes = SK_ARRAY_COUNT(text); const SkScalar xpos[] = { 10, 20 }; recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint()); const SkPoint pos[] = { {40, 50}, {60, 70} }; recorder.drawPosText(text, bytes, pos, SkPaint()); SkAutoTMalloc<SkRect> bounds(record.count()); SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, bounds); // We can make these next assertions confidently because SkRecordFillBounds // builds its bounds by overestimating font metrics in a platform-independent way. // If that changes, these tests will need to be more flexible. REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0, 0, 140, 60))); REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 20, 180, 100))); }
// Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures. DEF_GPUTEST_FOR_NULLGL_CONTEXT(GrTextureMipMapInvalidationTest, reporter, ctxInfo) { auto isMipped = [] (SkSurface* surf) { const GrTexture* texture = surf->makeImageSnapshot()->getTexture(); return GrMipMapped::kYes == texture->texturePriv().mipMapped(); }; auto mipsAreDirty = [] (SkSurface* surf) { return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty(); }; GrContext* context = ctxInfo.grContext(); auto info = SkImageInfo::MakeN32Premul(256, 256); auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info); auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info); // Draw something just in case we ever had a solid color optimization surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint()); surf1->getCanvas()->flush(); // No mipmaps initially REPORTER_ASSERT(reporter, !isMipped(surf1.get())); // Painting with downscale and medium filter quality should result in mipmap creation SkPaint paint; paint.setFilterQuality(kMedium_SkFilterQuality); surf2->getCanvas()->scale(0.2f, 0.2f); surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint); surf2->getCanvas()->flush(); REPORTER_ASSERT(reporter, isMipped(surf1.get())); REPORTER_ASSERT(reporter, !mipsAreDirty(surf1.get())); // Changing the contents of the surface should invalidate the mipmap, but not de-allocate surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint()); surf1->getCanvas()->flush(); REPORTER_ASSERT(reporter, isMipped(surf1.get())); REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get())); }
DEF_TEST(RecordDraw_Culling, r) { // Record these 7 drawing commands verbatim. SkRecord record; SkRecorder recorder(&record, W, H); recorder.pushCull(SkRect::MakeWH(100, 100)); recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint()); recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint()); recorder.pushCull(SkRect::MakeWH(5, 5)); recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint()); recorder.popCull(); recorder.popCull(); // Take a pass over to match up pushCulls and popCulls. SkRecordAnnotateCullingPairs(&record); // This clip intersects the outer cull, but allows us to quick reject the inner one. SkRecord clipped; record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped); // We'll keep the clipRect call from above, and the outer two drawRects, and the push/pop pair. // If culling weren't working, we'd see 8 commands recorded here. REPORTER_ASSERT(r, 5 == clipped.count()); }
static SkImage* make_image() { SkImageInfo info = SkImageInfo::MakeN32(N, N, kOpaque_SkAlphaType); SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); SkCanvas* canvas = surface->getCanvas(); canvas->drawColor(SK_ColorWHITE); SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); path.addRect(SkRect::MakeWH(N/2, N)); path.addRect(SkRect::MakeWH(N, N/2)); path.moveTo(0, 0); path.lineTo(N, 0); path.lineTo(0, N); path.close(); canvas->drawPath(path, SkPaint()); return surface->newImageSnapshot(); }