Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2015 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 #include "gm.h"
      9 #include "SkCanvas.h"
     10 #include "SkData.h"
     11 #include "SkImage.h"
     12 #include "SkPictureRecorder.h"
     13 #include "SkSurface.h"
     14 
     15 static void draw_something(SkCanvas* canvas, const SkRect& bounds) {
     16     SkPaint paint;
     17     paint.setAntiAlias(true);
     18     paint.setColor(SK_ColorRED);
     19     paint.setStyle(SkPaint::kStroke_Style);
     20     paint.setStrokeWidth(10);
     21     canvas->drawRect(bounds, paint);
     22     paint.setStyle(SkPaint::kFill_Style);
     23     paint.setColor(SK_ColorBLUE);
     24     canvas->drawOval(bounds, paint);
     25 }
     26 
     27 typedef SkImage* (*ImageMakerProc)(GrContext*, const SkPicture*, const SkImageInfo&);
     28 
     29 static SkImage* make_raster(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
     30     SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
     31     surface->getCanvas()->clear(0);
     32     surface->getCanvas()->drawPicture(pic);
     33     return surface->newImageSnapshot();
     34 }
     35 
     36 static SkImage* make_texture(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
     37     if (!ctx) {
     38         return nullptr;
     39     }
     40     SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkBudgeted::kNo,
     41                                                                info, 0));
     42     surface->getCanvas()->clear(0);
     43     surface->getCanvas()->drawPicture(pic);
     44     return surface->newImageSnapshot();
     45 }
     46 
     47 static SkImage* make_pict_gen(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
     48     return SkImage::NewFromPicture(pic, info.dimensions(), nullptr, nullptr);
     49 }
     50 
     51 static SkImage* make_encode_gen(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
     52     SkAutoTUnref<SkImage> src(make_raster(ctx, pic, info));
     53     if (!src) {
     54         return nullptr;
     55     }
     56     SkAutoTUnref<SkData> encoded(src->encode(SkImageEncoder::kPNG_Type, 100));
     57     if (!encoded) {
     58         return nullptr;
     59     }
     60     return SkImage::NewFromEncoded(encoded);
     61 }
     62 
     63 const ImageMakerProc gProcs[] = {
     64     make_raster,
     65     make_texture,
     66     make_pict_gen,
     67     make_encode_gen,
     68 };
     69 
     70 /*
     71  *  Exercise drawing pictures inside an image, showing that the image version is pixelated
     72  *  (correctly) when it is inside an image.
     73  */
     74 class ImageShaderGM : public skiagm::GM {
     75     SkAutoTUnref<SkPicture> fPicture;
     76 
     77 public:
     78     ImageShaderGM() {}
     79 
     80 protected:
     81     SkString onShortName() override {
     82         return SkString("image-shader");
     83     }
     84 
     85     SkISize onISize() override {
     86         return SkISize::Make(850, 450);
     87     }
     88 
     89     void onOnceBeforeDraw() override {
     90         const SkRect bounds = SkRect::MakeWH(100, 100);
     91         SkPictureRecorder recorder;
     92         draw_something(recorder.beginRecording(bounds), bounds);
     93         fPicture.reset(recorder.endRecording());
     94     }
     95 
     96     void testImage(SkCanvas* canvas, SkImage* image) {
     97         SkAutoCanvasRestore acr(canvas, true);
     98 
     99         canvas->drawImage(image, 0, 0);
    100         canvas->translate(0, 120);
    101 
    102         const SkShader::TileMode tile = SkShader::kRepeat_TileMode;
    103         const SkMatrix localM = SkMatrix::MakeTrans(-50, -50);
    104         SkAutoTUnref<SkShader> shader(image->newShader(tile, tile, &localM));
    105         SkPaint paint;
    106         paint.setAntiAlias(true);
    107         paint.setShader(shader);
    108         canvas->drawCircle(50, 50, 50, paint);
    109     }
    110 
    111     void onDraw(SkCanvas* canvas) override {
    112         canvas->translate(20, 20);
    113 
    114         const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    115 
    116         for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
    117             SkAutoTUnref<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture, info));
    118             if (image) {
    119                 this->testImage(canvas, image);
    120             }
    121             canvas->translate(120, 0);
    122         }
    123     }
    124 
    125 private:
    126     typedef skiagm::GM INHERITED;
    127 };
    128 DEF_GM( return new ImageShaderGM; )
    129 
    130