1
#include "SampleCode.h"
2
#include "SkDumpCanvas.h"
6
#include "SkGradientShader.h"
7
#include "SkGraphics.h"
8
#include "SkImageDecoder.h"
10
#include "SkPicture.h"
15
#include "SkColorPriv.h"
16
#include "SkColorFilter.h"
19
#include "SkTypeface.h"
20
#include "SkXfermode.h"
23
#include "SkXMLParser.h"
25
class SignalShape : public SkShape {
27
SignalShape() : fSignal(0) {}
29
SkShape* setSignal(int n) {
35
virtual void onDraw(SkCanvas* canvas) {
36
SkDebugf("---- sc %d\n", canvas->getSaveCount() - 1);
43
static SkPMColor SignalProc(SkPMColor src, SkPMColor dst) {
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.
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().
55
static void test_saveRestoreCulling() {
57
SignalShape signalShape;
60
SkRect r = SkRect::MakeWH(0, 0);
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));
67
canvas->drawShape(signalShape.setSignal(2));
69
canvas->drawShape(signalShape.setSignal(3));
72
canvas->drawShape(signalShape.setSignal(4));
73
canvas->restoreToCount(n);
74
canvas->drawShape(signalShape.setSignal(5));
76
canvas->drawShape(signalShape.setSignal(6));
77
SkASSERT(canvas->getSaveCount() == startN);
80
bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
86
///////////////////////////////////////////////////////////////////////////////
88
#include "SkImageRef_GlobalPool.h"
90
static SkBitmap load_bitmap() {
91
SkStream* stream = new SkFILEStream("/skimages/sesame_street_ensemble-hp.jpg");
92
SkAutoUnref aur(stream);
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();
103
static void drawCircle(SkCanvas* canvas, int r, SkColor color) {
105
paint.setAntiAlias(true);
106
paint.setColor(color);
108
canvas->drawCircle(SkIntToScalar(r), SkIntToScalar(r), SkIntToScalar(r),
112
class PictureView : public SkView {
116
SkImageRef_GlobalPool::SetRAMBudget(16 * 1024);
118
fBitmap = load_bitmap();
120
fPicture = new SkPicture;
121
SkCanvas* canvas = fPicture->beginRecording(100, 100);
123
paint.setAntiAlias(true);
125
canvas->drawBitmap(fBitmap, 0, 0, NULL);
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();
141
test_saveRestoreCulling();
144
virtual ~PictureView() {
149
// overrides from SkEventSink
150
virtual bool onQuery(SkEvent* evt) {
151
if (SampleCode::TitleQ(*evt)) {
152
SampleCode::TitleR(evt, "Picture");
155
return this->INHERITED::onQuery(evt);
158
void drawBG(SkCanvas* canvas) {
159
// canvas->drawColor(0xFFDDDDDD);
160
canvas->drawColor(SK_ColorWHITE);
161
// canvas->drawColor(SK_ColorBLACK);
164
void drawSomething(SkCanvas* canvas) {
168
canvas->scale(0.5f, 0.5f);
169
canvas->drawBitmap(fBitmap, 0, 0, NULL);
172
const char beforeStr[] = "before circle";
173
const char afterStr[] = "after circle";
175
paint.setAntiAlias(true);
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),
189
virtual void onDraw(SkCanvas* canvas) {
190
this->drawBG(canvas);
192
drawSomething(canvas);
194
SkPicture* pict = new SkPicture;
195
SkAutoUnref aur(pict);
197
drawSomething(pict->beginRecording(100, 100));
198
pict->endRecording();
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);
208
canvas->translate(SkIntToScalar(200), SkIntToScalar(150));
209
canvas->scale(SK_Scalar1, -SK_Scalar1);
210
canvas->translate(0, -SkIntToScalar(50));
211
canvas->drawPicture(*pict);
215
canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
216
canvas->scale(-SK_Scalar1, SK_Scalar1);
217
canvas->translate(-SkIntToScalar(100), 0);
218
canvas->drawPicture(*pict);
222
SkDebugfDumper dumper;
223
SkDumpCanvas dumpCanvas(&dumper);
224
dumpCanvas.drawPicture(*pict);
227
// test that we can re-record a subpicture, and see the results
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);
238
#define INVAL_ALL_TYPE "inval-all"
240
void delayInval(SkMSec delay) {
241
(new SkEvent(INVAL_ALL_TYPE))->post(this->getSinkID(), delay);
244
virtual bool onEvent(const SkEvent& evt) {
245
if (evt.isType(INVAL_ALL_TYPE)) {
249
return this->INHERITED::onEvent(evt);
253
SkPicture* fSubPicture;
255
typedef SkView INHERITED;
258
//////////////////////////////////////////////////////////////////////////////
260
static SkView* MyFactory() { return new PictureView; }
261
static SkViewRegister reg(MyFactory);