image.cpp revision 432789972c1e1f8a66165c75a250dba1853efa08
1/*
2 * Copyright 2011 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 "SkSurface.h"
10#include "SkCanvas.h"
11#include "SkDecodingImageGenerator.h"
12#include "SkStream.h"
13#include "SkData.h"
14
15#if SK_SUPPORT_GPU
16#include "GrContext.h"
17#endif
18
19static void drawJpeg(SkCanvas* canvas, const SkISize& size) {
20    // TODO: Make this draw a file that is checked in, so it can
21    // be exercised on machines other than mike's. Will require a
22    // rebaseline.
23    SkAutoDataUnref data(SkData::NewFromFileName("/Users/mike/Downloads/skia.google.jpeg"));
24    if (NULL == data.get()) {
25        return;
26    }
27    SkImage* image = SkImage::NewFromGenerator(
28                SkDecodingImageGenerator::Create(data, SkDecodingImageGenerator::Options()));
29    if (image) {
30        SkAutoCanvasRestore acr(canvas, true);
31        canvas->scale(size.width() * 1.0f / image->width(),
32                      size.height() * 1.0f / image->height());
33        canvas->drawImage(image, 0, 0, NULL);
34        image->unref();
35    }
36}
37
38static void drawContents(SkSurface* surface, SkColor fillC) {
39    SkSize size = SkSize::Make(SkIntToScalar(surface->width()),
40                               SkIntToScalar(surface->height()));
41    SkCanvas* canvas = surface->getCanvas();
42
43    SkScalar stroke = size.fWidth / 10;
44    SkScalar radius = (size.fWidth - stroke) / 2;
45
46    SkPaint paint;
47
48    paint.setAntiAlias(true);
49    paint.setColor(fillC);
50    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
51
52    paint.setStyle(SkPaint::kStroke_Style);
53    paint.setStrokeWidth(stroke);
54    paint.setColor(SK_ColorBLACK);
55    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
56}
57
58static void test_surface(SkCanvas* canvas, SkSurface* surf, bool usePaint) {
59    drawContents(surf, SK_ColorRED);
60    SkImage* imgR = surf->newImageSnapshot();
61
62    if (true) {
63        SkImage* imgR2 = surf->newImageSnapshot();
64        SkASSERT(imgR == imgR2);
65        imgR2->unref();
66    }
67
68    drawContents(surf, SK_ColorGREEN);
69    SkImage* imgG = surf->newImageSnapshot();
70
71    // since we've drawn after we snapped imgR, imgG will be a different obj
72    SkASSERT(imgR != imgG);
73
74    drawContents(surf, SK_ColorBLUE);
75
76    SkPaint paint;
77//    paint.setFilterBitmap(true);
78//    paint.setAlpha(0x80);
79
80    canvas->drawImage(imgR, 0, 0, usePaint ? &paint : NULL);
81    canvas->drawImage(imgG, 0, 80, usePaint ? &paint : NULL);
82    surf->draw(canvas, 0, 160, usePaint ? &paint : NULL);
83
84    SkRect src1, src2, src3;
85    src1.iset(0, 0, surf->width(), surf->height());
86    src2.iset(-surf->width() / 2, -surf->height() / 2,
87             surf->width(), surf->height());
88    src3.iset(0, 0, surf->width() / 2, surf->height() / 2);
89
90    SkRect dst1, dst2, dst3, dst4;
91    dst1.set(0, 240, 65, 305);
92    dst2.set(0, 320, 65, 385);
93    dst3.set(0, 400, 65, 465);
94    dst4.set(0, 480, 65, 545);
95
96    canvas->drawImageRect(imgR, &src1, dst1, usePaint ? &paint : NULL);
97    canvas->drawImageRect(imgG, &src2, dst2, usePaint ? &paint : NULL);
98    canvas->drawImageRect(imgR, &src3, dst3, usePaint ? &paint : NULL);
99    canvas->drawImageRect(imgG, NULL, dst4, usePaint ? &paint : NULL);
100
101    imgG->unref();
102    imgR->unref();
103}
104
105class ImageGM : public skiagm::GM {
106    void*   fBuffer;
107    size_t  fBufferSize;
108    SkSize  fSize;
109    enum {
110        W = 64,
111        H = 64,
112        RB = W * 4 + 8,
113    };
114public:
115    ImageGM() {
116        fBufferSize = RB * H;
117        fBuffer = sk_malloc_throw(fBufferSize);
118        fSize.set(SkIntToScalar(W), SkIntToScalar(H));
119    }
120
121    virtual ~ImageGM() {
122        sk_free(fBuffer);
123    }
124
125
126protected:
127    virtual SkString onShortName() {
128        return SkString("image-surface");
129    }
130
131    virtual SkISize onISize() {
132        return SkISize::Make(960, 1200);
133    }
134
135    virtual void onDraw(SkCanvas* canvas) {
136        drawJpeg(canvas, this->getISize());
137
138        canvas->scale(2, 2);
139
140        static const char* kLabel1 = "Original Img";
141        static const char* kLabel2 = "Modified Img";
142        static const char* kLabel3 = "Cur Surface";
143        static const char* kLabel4 = "Full Crop";
144        static const char* kLabel5 = "Over-crop";
145        static const char* kLabel6 = "Upper-left";
146        static const char* kLabel7 = "No Crop";
147
148        static const char* kLabel8 = "Pre-Alloc Img";
149        static const char* kLabel9 = "New Alloc Img";
150        static const char* kLabel10 = "Null Paint";
151        static const char* kLabel11 = "GPU";
152
153        SkPaint textPaint;
154        textPaint.setAntiAlias(true);
155        sk_tool_utils::set_portable_typeface(&textPaint);
156        textPaint.setTextSize(8);
157
158        canvas->drawText(kLabel1, strlen(kLabel1), 10,  60, textPaint);
159        canvas->drawText(kLabel2, strlen(kLabel2), 10, 140, textPaint);
160        canvas->drawText(kLabel3, strlen(kLabel3), 10, 220, textPaint);
161        canvas->drawText(kLabel4, strlen(kLabel4), 10, 300, textPaint);
162        canvas->drawText(kLabel5, strlen(kLabel5), 10, 380, textPaint);
163        canvas->drawText(kLabel6, strlen(kLabel6), 10, 460, textPaint);
164        canvas->drawText(kLabel7, strlen(kLabel7), 10, 540, textPaint);
165
166        canvas->drawText(kLabel8, strlen(kLabel8),  80, 10, textPaint);
167        canvas->drawText(kLabel9, strlen(kLabel9), 160, 10, textPaint);
168        canvas->drawText(kLabel10, strlen(kLabel10), 250, 10, textPaint);
169        canvas->drawText(kLabel11, strlen(kLabel11), 320, 10, textPaint);
170
171        canvas->translate(80, 20);
172
173        // since we draw into this directly, we need to start fresh
174        sk_bzero(fBuffer, fBufferSize);
175
176        SkImageInfo info = SkImageInfo::MakeN32Premul(W, H);
177        SkAutoTUnref<SkSurface> surf0(SkSurface::NewRasterDirect(info, fBuffer, RB));
178        SkAutoTUnref<SkSurface> surf1(SkSurface::NewRaster(info));
179#if SK_SUPPORT_GPU
180        GrContext* ctx = canvas->getGrContext();
181
182        SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info));
183#endif
184
185        test_surface(canvas, surf0, true);
186        canvas->translate(80, 0);
187        test_surface(canvas, surf1, true);
188#if SK_SUPPORT_GPU
189        if (ctx) {
190            canvas->translate(80, 0);
191            test_surface(canvas, surf4, true);
192        }
193#endif
194    }
195
196    virtual uint32_t onGetFlags() const SK_OVERRIDE {
197        return GM::kSkipPicture_Flag | GM::kSkipPipe_Flag;
198    }
199
200private:
201    typedef skiagm::GM INHERITED;
202};
203
204//////////////////////////////////////////////////////////////////////////////
205
206static skiagm::GM* MyFactory(void*) { return new ImageGM; }
207static skiagm::GMRegistry reg(MyFactory);
208