1/* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8// This is a GPU-backend specific test. 9 10#include "tests/Test.h" 11 12using namespace sk_gpu_test; 13 14#include "tools/gpu/GrContextFactory.h" 15 16#include "include/core/SkBitmap.h" 17#include "include/core/SkCanvas.h" 18#include "include/core/SkSurface.h" 19#include "include/gpu/GrDirectContext.h" 20#include "src/core/SkImagePriv.h" 21 22static bool surface_is_expected_color(SkSurface* surf, const SkImageInfo& ii, SkColor color) { 23 SkBitmap bm; 24 bm.allocPixels(ii); 25 26 surf->readPixels(bm, 0, 0); 27 28 for (int y = 0; y < bm.height(); ++y) { 29 for (int x = 0; x < bm.width(); ++x) { 30 if (bm.getColor(x, y) != color) { 31 return false; 32 } 33 } 34 } 35 36 return true; 37} 38 39static void basic_test(skiatest::Reporter* reporter, GrRecordingContext* rContext) { 40 const SkImageInfo ii = SkImageInfo::Make(64, 64, kN32_SkColorType, kPremul_SkAlphaType); 41 42 SkBitmap bm; 43 bm.allocPixels(ii); 44 45 SkCanvas bmCanvas(bm); 46 bmCanvas.clear(SK_ColorRED); 47 48 // We start off with the raster image being all red. 49 sk_sp<SkImage> img = SkMakeImageFromRasterBitmap(bm, kNever_SkCopyPixelsMode); 50 51 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(rContext, SkBudgeted::kYes, ii); 52 SkCanvas* canvas = gpuSurface->getCanvas(); 53 54 // w/o pinning - the gpu draw always reflects the current state of the underlying bitmap 55 { 56 canvas->drawImage(img, 0, 0); 57 REPORTER_ASSERT(reporter, surface_is_expected_color(gpuSurface.get(), ii, SK_ColorRED)); 58 59 bmCanvas.clear(SK_ColorGREEN); 60 61 canvas->drawImage(img, 0, 0); 62 REPORTER_ASSERT(reporter, surface_is_expected_color(gpuSurface.get(), ii, SK_ColorGREEN)); 63 } 64 65 // w/ pinning - the gpu draw is stuck at the pinned state 66 { 67 SkImage_pinAsTexture(img.get(), rContext); // pin at blue 68 69 canvas->drawImage(img, 0, 0); 70 REPORTER_ASSERT(reporter, surface_is_expected_color(gpuSurface.get(), ii, SK_ColorGREEN)); 71 72 bmCanvas.clear(SK_ColorBLUE); 73 74 canvas->drawImage(img, 0, 0); 75 REPORTER_ASSERT(reporter, surface_is_expected_color(gpuSurface.get(), ii, SK_ColorGREEN)); 76 77 SkImage_unpinAsTexture(img.get(), rContext); 78 } 79 80 // once unpinned local changes will be picked up 81 { 82 canvas->drawImage(img, 0, 0); 83 REPORTER_ASSERT(reporter, surface_is_expected_color(gpuSurface.get(), ii, SK_ColorBLUE)); 84 } 85} 86 87// Deleting the context while there are still pinned images shouldn't result in a crash. 88static void cleanup_test(skiatest::Reporter* reporter) { 89 90 const SkImageInfo ii = SkImageInfo::Make(64, 64, kN32_SkColorType, kPremul_SkAlphaType); 91 92 SkBitmap bm; 93 bm.allocPixels(ii); 94 95 SkCanvas bmCanvas(bm); 96 bmCanvas.clear(SK_ColorRED); 97 98 GrMockOptions options; 99 sk_sp<GrDirectContext> mockContext = GrDirectContext::MakeMock(&options); 100 101 for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) { 102 GrContextFactory::ContextType ctxType = (GrContextFactory::ContextType) i; 103 104 { 105 sk_sp<SkImage> img; 106 GrDirectContext* dContext = nullptr; 107 108 { 109 GrContextFactory testFactory; 110 ContextInfo info = testFactory.getContextInfo(ctxType); 111 dContext = info.directContext(); 112 if (!dContext) { 113 continue; 114 } 115 116 img = SkMakeImageFromRasterBitmap(bm, kNever_SkCopyPixelsMode); 117 if (!SkImage_pinAsTexture(img.get(), dContext)) { 118 continue; 119 } 120 // Pinning on a second context should be blocked. 121 REPORTER_ASSERT(reporter, !SkImage_pinAsTexture(img.get(), mockContext.get())); 122 } 123 124 // The context used to pin the image is gone at this point! 125 // "context" isn't technically used in this call but it can't be null! 126 // We don't really want to support this use case but it currently happens. 127 SkImage_unpinAsTexture(img.get(), dContext); 128 } 129 } 130} 131 132DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PinnedImageTest, reporter, ctxInfo) { 133 basic_test(reporter, ctxInfo.directContext()); 134 cleanup_test(reporter); 135} 136