~jammy-zhou/+junk/skia

« back to all changes in this revision

Viewing changes to samplecode/.svn/text-base/SamplePicture.cpp.svn-base

  • Committer: Jammy Zhou
  • Date: 2010-11-05 22:47:35 UTC
  • Revision ID: jammy.zhou@linaro.org-20101105224735-i1miyqbyxwslg7t2
initial version (upstream r622)

http://code.google.com/p/skia/source/list

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "SampleCode.h"
 
2
#include "SkDumpCanvas.h"
 
3
#include "SkView.h"
 
4
#include "SkCanvas.h"
 
5
#include "Sk64.h"
 
6
#include "SkGradientShader.h"
 
7
#include "SkGraphics.h"
 
8
#include "SkImageDecoder.h"
 
9
#include "SkPath.h"
 
10
#include "SkPicture.h"
 
11
#include "SkRandom.h"
 
12
#include "SkRegion.h"
 
13
#include "SkShader.h"
 
14
#include "SkUtils.h"
 
15
#include "SkColorPriv.h"
 
16
#include "SkColorFilter.h"
 
17
#include "SkShape.h"
 
18
#include "SkTime.h"
 
19
#include "SkTypeface.h"
 
20
#include "SkXfermode.h"
 
21
 
 
22
#include "SkStream.h"
 
23
#include "SkXMLParser.h"
 
24
 
 
25
class SignalShape : public SkShape {
 
26
public:
 
27
    SignalShape() : fSignal(0) {}
 
28
 
 
29
    SkShape* setSignal(int n) {
 
30
        fSignal = n;
 
31
        return this;
 
32
    }
 
33
 
 
34
protected:
 
35
    virtual void onDraw(SkCanvas* canvas) {
 
36
        SkDebugf("---- sc %d\n", canvas->getSaveCount() - 1);
 
37
    }
 
38
 
 
39
private:
 
40
    int fSignal;
 
41
};
 
42
 
 
43
static SkPMColor SignalProc(SkPMColor src, SkPMColor dst) {
 
44
    return dst;
 
45
}
 
46
 
 
47
/*  Picture playback will skip blocks of draw calls that follow a clip() call
 
48
    that returns empty, and jump down to the corresponding restore() call.
 
49
 
 
50
    This is a great preformance win for drawing very large/tall pictures with
 
51
    a small visible window (think scrolling a long document). These tests make
 
52
    sure that (a) we are performing the culling, and (b) we don't get confused
 
53
    by nested save() calls, nor by calls to restoreToCount().
 
54
 */
 
55
static void test_saveRestoreCulling() {
 
56
    SkPaint signalPaint;
 
57
    SignalShape signalShape;
 
58
 
 
59
    SkPicture pic;
 
60
    SkRect r = SkRect::MakeWH(0, 0);
 
61
    int n;
 
62
    SkCanvas* canvas = pic.beginRecording(100, 100);
 
63
    int startN = canvas->getSaveCount();
 
64
    SkDebugf("---- start sc %d\n", startN);
 
65
    canvas->drawShape(signalShape.setSignal(1));
 
66
    canvas->save();
 
67
    canvas->drawShape(signalShape.setSignal(2));
 
68
    n = canvas->save();
 
69
    canvas->drawShape(signalShape.setSignal(3));
 
70
    canvas->save();
 
71
    canvas->clipRect(r);
 
72
    canvas->drawShape(signalShape.setSignal(4));
 
73
    canvas->restoreToCount(n);
 
74
    canvas->drawShape(signalShape.setSignal(5));
 
75
    canvas->restore();
 
76
    canvas->drawShape(signalShape.setSignal(6));
 
77
    SkASSERT(canvas->getSaveCount() == startN);
 
78
 
 
79
    SkBitmap bm;
 
80
    bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
 
81
    bm.allocPixels();
 
82
    SkCanvas c(bm);
 
83
    c.drawPicture(pic);
 
84
}
 
85
 
 
86
///////////////////////////////////////////////////////////////////////////////
 
87
 
 
88
#include "SkImageRef_GlobalPool.h"
 
89
 
 
90
static SkBitmap load_bitmap() {
 
91
    SkStream* stream = new SkFILEStream("/skimages/sesame_street_ensemble-hp.jpg");
 
92
    SkAutoUnref aur(stream);
 
93
    
 
94
    SkBitmap bm;
 
95
    if (SkImageDecoder::DecodeStream(stream, &bm, SkBitmap::kNo_Config,
 
96
                                     SkImageDecoder::kDecodeBounds_Mode)) {
 
97
        SkPixelRef* pr = new SkImageRef_GlobalPool(stream, bm.config(), 1);
 
98
        bm.setPixelRef(pr)->unref();
 
99
    }
 
100
    return bm;
 
101
}
 
102
 
 
103
static void drawCircle(SkCanvas* canvas, int r, SkColor color) {
 
104
    SkPaint paint;
 
105
    paint.setAntiAlias(true);
 
106
    paint.setColor(color);
 
107
 
 
108
    canvas->drawCircle(SkIntToScalar(r), SkIntToScalar(r), SkIntToScalar(r),
 
109
                       paint);
 
110
}
 
111
 
 
112
class PictureView : public SkView {
 
113
    SkBitmap fBitmap;
 
114
public:
 
115
        PictureView() {
 
116
        SkImageRef_GlobalPool::SetRAMBudget(16 * 1024);
 
117
 
 
118
        fBitmap = load_bitmap();
 
119
 
 
120
        fPicture = new SkPicture;
 
121
        SkCanvas* canvas = fPicture->beginRecording(100, 100);
 
122
        SkPaint paint;
 
123
        paint.setAntiAlias(true);
 
124
        
 
125
        canvas->drawBitmap(fBitmap, 0, 0, NULL);
 
126
 
 
127
        drawCircle(canvas, 50, SK_ColorBLACK);
 
128
        fSubPicture = new SkPicture;
 
129
        canvas->drawPicture(*fSubPicture);
 
130
        canvas->translate(SkIntToScalar(50), 0);
 
131
        canvas->drawPicture(*fSubPicture);
 
132
        canvas->translate(0, SkIntToScalar(50));
 
133
        canvas->drawPicture(*fSubPicture);
 
134
        canvas->translate(SkIntToScalar(-50), 0);
 
135
        canvas->drawPicture(*fSubPicture);
 
136
        // fPicture now has (4) references to us. We can release ours, and just
 
137
        // unref fPicture in our destructor, and it will in turn take care of
 
138
        // the other references to fSubPicture
 
139
        fSubPicture->unref();
 
140
 
 
141
        test_saveRestoreCulling();
 
142
    }
 
143
    
 
144
    virtual ~PictureView() {
 
145
        fPicture->unref();
 
146
    }
 
147
    
 
148
protected:
 
149
    // overrides from SkEventSink
 
150
    virtual bool onQuery(SkEvent* evt) {
 
151
        if (SampleCode::TitleQ(*evt)) {
 
152
            SampleCode::TitleR(evt, "Picture");
 
153
            return true;
 
154
        }
 
155
        return this->INHERITED::onQuery(evt);
 
156
    }
 
157
 
 
158
    void drawBG(SkCanvas* canvas) {
 
159
//        canvas->drawColor(0xFFDDDDDD);
 
160
        canvas->drawColor(SK_ColorWHITE);
 
161
   //     canvas->drawColor(SK_ColorBLACK);
 
162
    }
 
163
    
 
164
    void drawSomething(SkCanvas* canvas) {
 
165
        SkPaint paint;
 
166
 
 
167
        canvas->save();
 
168
        canvas->scale(0.5f, 0.5f);
 
169
        canvas->drawBitmap(fBitmap, 0, 0, NULL);
 
170
        canvas->restore();
 
171
 
 
172
        const char beforeStr[] = "before circle";
 
173
        const char afterStr[] = "after circle";
 
174
 
 
175
        paint.setAntiAlias(true);
 
176
    
 
177
        paint.setColor(SK_ColorRED);
 
178
        canvas->drawData(beforeStr, sizeof(beforeStr));
 
179
        canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
 
180
                           SkIntToScalar(40), paint);
 
181
        canvas->drawData(afterStr, sizeof(afterStr));
 
182
        paint.setColor(SK_ColorBLACK);
 
183
        paint.setTextSize(SkIntToScalar(40));
 
184
        canvas->drawText("Picture", 7, SkIntToScalar(50), SkIntToScalar(62),
 
185
                         paint);
 
186
        
 
187
    }
 
188
 
 
189
    virtual void onDraw(SkCanvas* canvas) {
 
190
        this->drawBG(canvas);
 
191
 
 
192
        drawSomething(canvas);
 
193
 
 
194
        SkPicture* pict = new SkPicture;
 
195
        SkAutoUnref aur(pict);
 
196
 
 
197
        drawSomething(pict->beginRecording(100, 100));
 
198
        pict->endRecording();
 
199
    
 
200
        canvas->save();
 
201
        canvas->translate(SkIntToScalar(300), SkIntToScalar(50));
 
202
        canvas->scale(-SK_Scalar1, -SK_Scalar1);
 
203
        canvas->translate(-SkIntToScalar(100), -SkIntToScalar(50));
 
204
        canvas->drawPicture(*pict);
 
205
        canvas->restore();
 
206
 
 
207
        canvas->save();
 
208
        canvas->translate(SkIntToScalar(200), SkIntToScalar(150));
 
209
        canvas->scale(SK_Scalar1, -SK_Scalar1);
 
210
        canvas->translate(0, -SkIntToScalar(50));
 
211
        canvas->drawPicture(*pict);
 
212
        canvas->restore();
 
213
        
 
214
        canvas->save();
 
215
        canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
 
216
        canvas->scale(-SK_Scalar1, SK_Scalar1);
 
217
        canvas->translate(-SkIntToScalar(100), 0);
 
218
        canvas->drawPicture(*pict);
 
219
        canvas->restore();
 
220
 
 
221
        if (false) {
 
222
            SkDebugfDumper dumper;
 
223
            SkDumpCanvas dumpCanvas(&dumper);
 
224
            dumpCanvas.drawPicture(*pict);
 
225
        }
 
226
        
 
227
        // test that we can re-record a subpicture, and see the results
 
228
        
 
229
        SkRandom rand(SampleCode::GetAnimTime());
 
230
        canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
 
231
        drawCircle(fSubPicture->beginRecording(50, 50), 25,
 
232
                   rand.nextU() | 0xFF000000);
 
233
        canvas->drawPicture(*fPicture);
 
234
        delayInval(500);
 
235
    }
 
236
    
 
237
private:
 
238
    #define INVAL_ALL_TYPE  "inval-all"
 
239
    
 
240
    void delayInval(SkMSec delay) {
 
241
        (new SkEvent(INVAL_ALL_TYPE))->post(this->getSinkID(), delay);
 
242
    }
 
243
    
 
244
    virtual bool onEvent(const SkEvent& evt) {
 
245
        if (evt.isType(INVAL_ALL_TYPE)) {
 
246
            this->inval(NULL);
 
247
            return true;
 
248
        }
 
249
        return this->INHERITED::onEvent(evt);
 
250
    }
 
251
 
 
252
    SkPicture*  fPicture;
 
253
    SkPicture*  fSubPicture;
 
254
 
 
255
    typedef SkView INHERITED;
 
256
};
 
257
 
 
258
//////////////////////////////////////////////////////////////////////////////
 
259
 
 
260
static SkView* MyFactory() { return new PictureView; }
 
261
static SkViewRegister reg(MyFactory);
 
262