| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "gm.h" | 8 #include "gm.h" |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkImage.h" | 10 #include "SkImage.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 canvas->restore(); | 93 canvas->restore(); |
| 94 } | 94 } |
| 95 | 95 |
| 96 private: | 96 private: |
| 97 typedef skiagm::GM INHERITED; | 97 typedef skiagm::GM INHERITED; |
| 98 }; | 98 }; |
| 99 DEF_GM( return new ImagePictGM; ) | 99 DEF_GM( return new ImagePictGM; ) |
| 100 | 100 |
| 101 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 101 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 102 | 102 |
| 103 static SkImageGenerator* make_pic_generator(GrContext*, SkPicture* pic) { |
| 104 SkMatrix matrix; |
| 105 matrix.setTranslate(-100, -100); |
| 106 return SkImageGenerator::NewFromPicture(SkISize::Make(100, 100), pic, &matri
x, nullptr); |
| 107 } |
| 108 |
| 109 class RasterGenerator : public SkImageGenerator { |
| 110 public: |
| 111 RasterGenerator(const SkBitmap& bm) : SkImageGenerator(bm.info()), fBM(bm) {
} |
| 112 protected: |
| 113 bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
| 114 SkPMColor*, int*) override { |
| 115 return fBM.readPixels(info, pixels, rowBytes, 0, 0); |
| 116 } |
| 117 private: |
| 118 SkBitmap fBM; |
| 119 }; |
| 120 static SkImageGenerator* make_ras_generator(GrContext*, SkPicture* pic) { |
| 121 SkBitmap bm; |
| 122 bm.allocN32Pixels(100, 100); |
| 123 SkCanvas canvas(bm); |
| 124 canvas.clear(0); |
| 125 canvas.translate(-100, -100); |
| 126 canvas.drawPicture(pic); |
| 127 return new RasterGenerator(bm); |
| 128 } |
| 129 |
| 130 class EmptyGenerator : public SkImageGenerator { |
| 131 public: |
| 132 EmptyGenerator(const SkImageInfo& info) : SkImageGenerator(info) {} |
| 133 }; |
| 134 |
| 135 #if SK_SUPPORT_GPU |
| 136 class TextureGenerator : public SkImageGenerator { |
| 137 public: |
| 138 TextureGenerator(GrContext* ctx, const SkImageInfo& info, SkPicture* pic) |
| 139 : SkImageGenerator(info) |
| 140 , fCtx(SkRef(ctx)) |
| 141 { |
| 142 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurfac
e::kNo_Budgeted, |
| 143 info, 0)); |
| 144 surface->getCanvas()->clear(0); |
| 145 surface->getCanvas()->translate(-100, -100); |
| 146 surface->getCanvas()->drawPicture(pic); |
| 147 SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); |
| 148 fTexture.reset(SkRef(image->getTexture())); |
| 149 } |
| 150 protected: |
| 151 GrTexture* onGenerateTexture(GrContext* ctx, SkImageUsageType, const SkIRect
* subset) override { |
| 152 if (ctx) { |
| 153 SkASSERT(ctx == fCtx.get()); |
| 154 } |
| 155 |
| 156 if (!subset) { |
| 157 return SkRef(fTexture.get()); |
| 158 } |
| 159 // need to copy the subset into a new texture |
| 160 GrSurfaceDesc desc = fTexture->desc(); |
| 161 desc.fWidth = subset->width(); |
| 162 desc.fHeight = subset->height(); |
| 163 |
| 164 GrTexture* dst = fCtx->textureProvider()->createTexture(desc, false); |
| 165 fCtx->copySurface(dst, fTexture, *subset, SkIPoint::Make(0, 0)); |
| 166 return dst; |
| 167 } |
| 168 private: |
| 169 SkAutoTUnref<GrContext> fCtx; |
| 170 SkAutoTUnref<GrTexture> fTexture; |
| 171 }; |
| 172 static SkImageGenerator* make_tex_generator(GrContext* ctx, SkPicture* pic) { |
| 173 const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); |
| 174 |
| 175 if (!ctx) { |
| 176 return new EmptyGenerator(info); |
| 177 } |
| 178 return new TextureGenerator(ctx, info, pic); |
| 179 } |
| 180 #endif |
| 103 | 181 |
| 104 class ImageCacheratorGM : public skiagm::GM { | 182 class ImageCacheratorGM : public skiagm::GM { |
| 105 SkAutoTUnref<SkPicture> fPicture; | 183 SkString fName; |
| 184 SkImageGenerator* (*fFactory)(GrContext*, SkPicture*); |
| 185 SkAutoTUnref<SkPicture> fPicture; |
| 106 SkAutoTDelete<SkImageCacherator> fCache; | 186 SkAutoTDelete<SkImageCacherator> fCache; |
| 187 SkAutoTDelete<SkImageCacherator> fCacheSubset; |
| 107 | 188 |
| 108 public: | 189 public: |
| 109 ImageCacheratorGM() {} | 190 ImageCacheratorGM(const char suffix[], SkImageGenerator* (*factory)(GrContex
t*, SkPicture*)) |
| 191 : fFactory(factory) |
| 192 { |
| 193 fName.printf("image-cacherator-from-%s", suffix); |
| 194 } |
| 110 | 195 |
| 111 protected: | 196 protected: |
| 112 SkString onShortName() override { | 197 SkString onShortName() override { |
| 113 return SkString("image-cacherator"); | 198 return fName; |
| 114 } | 199 } |
| 115 | 200 |
| 116 SkISize onISize() override { | 201 SkISize onISize() override { |
| 117 return SkISize::Make(850, 450); | 202 return SkISize::Make(850, 450); |
| 118 } | 203 } |
| 119 | 204 |
| 120 void onOnceBeforeDraw() override { | 205 void onOnceBeforeDraw() override { |
| 121 const SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100); | 206 const SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100); |
| 122 SkPictureRecorder recorder; | 207 SkPictureRecorder recorder; |
| 123 draw_something(recorder.beginRecording(bounds), bounds); | 208 draw_something(recorder.beginRecording(bounds), bounds); |
| 124 fPicture.reset(recorder.endRecording()); | 209 fPicture.reset(recorder.endRecording()); |
| 210 } |
| 125 | 211 |
| 126 // extract enough just for the oval. | 212 void makeCaches(GrContext* ctx) { |
| 127 const SkISize size = SkISize::Make(100, 100); | 213 auto gen = fFactory(ctx, fPicture); |
| 214 SkDEBUGCODE(const uint32_t genID = gen->uniqueID();) |
| 215 fCache.reset(SkImageCacherator::NewFromGenerator(gen)); |
| 128 | 216 |
| 129 SkMatrix matrix; | 217 const SkIRect subset = SkIRect::MakeLTRB(50, 50, 100, 100); |
| 130 matrix.setTranslate(-100, -100); | 218 |
| 131 auto gen = SkImageGenerator::NewFromPicture(size, fPicture, &matrix, nul
lptr); | 219 gen = fFactory(ctx, fPicture); |
| 132 fCache.reset(SkImageCacherator::NewFromGenerator(gen)); | 220 SkDEBUGCODE(const uint32_t genSubsetID = gen->uniqueID();) |
| 221 fCacheSubset.reset(SkImageCacherator::NewFromGenerator(gen, &subset)); |
| 222 |
| 223 // whole caches should have the same ID as the generator. Subsets should
be diff |
| 224 SkASSERT(fCache->uniqueID() == genID); |
| 225 SkASSERT(fCacheSubset->uniqueID() != genID); |
| 226 SkASSERT(fCacheSubset->uniqueID() != genSubsetID); |
| 227 |
| 228 SkASSERT(fCache->info().dimensions() == SkISize::Make(100, 100)); |
| 229 SkASSERT(fCacheSubset->info().dimensions() == SkISize::Make(50, 50)); |
| 230 } |
| 231 |
| 232 static void draw_as_bitmap(SkCanvas* canvas, SkImageCacherator* cache, SkSca
lar x, SkScalar y) { |
| 233 SkBitmap bitmap; |
| 234 cache->lockAsBitmap(&bitmap); |
| 235 canvas->drawBitmap(bitmap, x, y); |
| 236 } |
| 237 |
| 238 static void draw_as_tex(SkCanvas* canvas, SkImageCacherator* cache, SkScalar
x, SkScalar y) { |
| 239 #if SK_SUPPORT_GPU |
| 240 SkAutoTUnref<GrTexture> texture(cache->lockAsTexture(canvas->getGrContex
t(), |
| 241 kUntiled_SkImageUsa
geType)); |
| 242 if (!texture) { |
| 243 return; |
| 244 } |
| 245 // No API to draw a GrTexture directly, so we cheat and create a private
image subclass |
| 246 SkAutoTUnref<SkImage> image(new SkImage_Gpu(cache->info().width(), cache
->info().height(), |
| 247 cache->uniqueID(), kPremul_S
kAlphaType, texture, |
| 248 0, SkSurface::kNo_Budgeted))
; |
| 249 canvas->drawImage(image, x, y); |
| 250 #endif |
| 133 } | 251 } |
| 134 | 252 |
| 135 void drawSet(SkCanvas* canvas) const { | 253 void drawSet(SkCanvas* canvas) const { |
| 136 SkMatrix matrix = SkMatrix::MakeTrans(-100, -100); | 254 SkMatrix matrix = SkMatrix::MakeTrans(-100, -100); |
| 137 canvas->drawPicture(fPicture, &matrix, nullptr); | 255 canvas->drawPicture(fPicture, &matrix, nullptr); |
| 138 | 256 |
| 139 { | 257 // Draw the tex first, so it doesn't hit a lucky cache from the raster v
ersion. This |
| 140 SkBitmap bitmap; | 258 // way we also can force the generateTexture call. |
| 141 fCache->lockAsBitmap(&bitmap); | 259 |
| 142 canvas->drawBitmap(bitmap, 150, 0); | 260 draw_as_tex(canvas, fCache, 310, 0); |
| 143 } | 261 draw_as_tex(canvas, fCacheSubset, 310+101, 0); |
| 144 #if SK_SUPPORT_GPU | 262 |
| 145 { | 263 draw_as_bitmap(canvas, fCache, 150, 0); |
| 146 SkAutoTUnref<GrTexture> texture(fCache->lockAsTexture(canvas->getGrC
ontext(), | 264 draw_as_bitmap(canvas, fCacheSubset, 150+101, 0); |
| 147 kUntiled_SkIm
ageUsageType)); | |
| 148 if (!texture) { | |
| 149 return; | |
| 150 } | |
| 151 // No API to draw a GrTexture directly, so we cheat and create a pri
vate image subclass | |
| 152 SkAutoTUnref<SkImage> image(new SkImage_Gpu(100, 100, fCache->genera
tor()->uniqueID(), | |
| 153 kPremul_SkAlphaType, tex
ture, 0, | |
| 154 SkSurface::kNo_Budgeted)
); | |
| 155 canvas->drawImage(image, 300, 0); | |
| 156 } | |
| 157 #endif | |
| 158 } | 265 } |
| 159 | 266 |
| 160 void onDraw(SkCanvas* canvas) override { | 267 void onDraw(SkCanvas* canvas) override { |
| 268 this->makeCaches(canvas->getGrContext()); |
| 269 |
| 161 canvas->translate(20, 20); | 270 canvas->translate(20, 20); |
| 162 | 271 |
| 163 this->drawSet(canvas); | 272 this->drawSet(canvas); |
| 164 | 273 |
| 165 canvas->save(); | 274 canvas->save(); |
| 166 canvas->translate(0, 130); | 275 canvas->translate(0, 130); |
| 167 canvas->scale(0.25f, 0.25f); | 276 canvas->scale(0.25f, 0.25f); |
| 168 this->drawSet(canvas); | 277 this->drawSet(canvas); |
| 169 canvas->restore(); | 278 canvas->restore(); |
| 170 | 279 |
| 171 canvas->save(); | 280 canvas->save(); |
| 172 canvas->translate(0, 200); | 281 canvas->translate(0, 200); |
| 173 canvas->scale(2, 2); | 282 canvas->scale(2, 2); |
| 174 this->drawSet(canvas); | 283 this->drawSet(canvas); |
| 175 canvas->restore(); | 284 canvas->restore(); |
| 176 } | 285 } |
| 177 | 286 |
| 178 private: | 287 private: |
| 179 typedef skiagm::GM INHERITED; | 288 typedef skiagm::GM INHERITED; |
| 180 }; | 289 }; |
| 181 DEF_GM( return new ImageCacheratorGM; ) | 290 DEF_GM( return new ImageCacheratorGM("picture", make_pic_generator); ) |
| 291 DEF_GM( return new ImageCacheratorGM("raster", make_ras_generator); ) |
| 292 #if SK_SUPPORT_GPU |
| 293 DEF_GM( return new ImageCacheratorGM("texture", make_tex_generator); ) |
| 294 #endif |
| 182 | 295 |
| 183 | 296 |
| 184 | 297 |
| OLD | NEW |