blob: 4000ed7e6c7f98abf9ee0f5a3759ef4f87922518 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SkCanvas.h"
2#include "SkDevice.h"
3#include "SkGLCanvas.h"
4#include "SkGraphics.h"
reed@android.comb08eb2b2009-01-06 20:16:26 +00005#include "SkImageEncoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00006#include "SkPaint.h"
7#include "SkPicture.h"
8#include "SkStream.h"
9#include "SkWindow.h"
10
11#include "SampleCode.h"
12
reed@android.com34245c72009-11-03 04:00:48 +000013SkView* create_overview(int, const SkViewFactory*);
14
reed@android.com6efdc472008-12-19 18:24:35 +000015//#define SK_SUPPORT_GL
16
17#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +000018#include <AGL/agl.h>
19#include <OpenGL/gl.h>
reed@android.com6efdc472008-12-19 18:24:35 +000020#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000021
22#define ANIMATING_EVENTTYPE "nextSample"
23#define ANIMATING_DELAY 750
24
25#define USE_OFFSCREEN
26
27SkViewRegister* SkViewRegister::gHead;
28SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
29 static bool gOnce;
30 if (!gOnce) {
31 gHead = NULL;
32 gOnce = true;
33 }
34
35 fChain = gHead;
36 gHead = this;
37}
38
reed@android.com6efdc472008-12-19 18:24:35 +000039#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +000040static AGLContext gAGLContext;
41
42static void init_gl(WindowRef wref) {
43 GLint major, minor;
44
45 aglGetVersion(&major, &minor);
46 SkDebugf("---- agl version %d %d\n", major, minor);
47
48 const GLint pixelAttrs[] = {
49 AGL_RGBA,
50 AGL_DEPTH_SIZE, 32,
51 AGL_OFFSCREEN,
52 AGL_NONE
53 };
54
55 AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
56 SkDebugf("----- agl format %p\n", format);
57 gAGLContext = aglCreateContext(format, NULL);
58 SkDebugf("----- agl context %p\n", gAGLContext);
59 aglDestroyPixelFormat(format);
60
61 aglEnable(gAGLContext, GL_BLEND);
62 aglEnable(gAGLContext, GL_LINE_SMOOTH);
63 aglEnable(gAGLContext, GL_POINT_SMOOTH);
64 aglEnable(gAGLContext, GL_POLYGON_SMOOTH);
65
66 aglSetCurrentContext(gAGLContext);
67}
68
69static void setup_offscreen_gl(const SkBitmap& offscreen, WindowRef wref) {
70 GLboolean success = true;
71
72#ifdef USE_OFFSCREEN
73 success = aglSetOffScreen(gAGLContext,
74 offscreen.width(),
75 offscreen.height(),
76 offscreen.rowBytes(),
77 offscreen.getPixels());
78#else
79 success = aglSetWindowRef(gAGLContext, wref);
80#endif
81
82 GLenum err = aglGetError();
83 if (err) {
84 SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
85 aglErrorString(err), offscreen.width(), offscreen.height());
86 }
87
88 glEnable(GL_BLEND);
89 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
90 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
91 glEnable(GL_TEXTURE_2D);
92
93 glClearColor(0, 0, 0, 0);
94 glClear(GL_COLOR_BUFFER_BIT);
95}
reed@android.com6efdc472008-12-19 18:24:35 +000096#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000097
98//////////////////////////////////////////////////////////////////////////////
99
100static const char gTitleEvtName[] = "SampleCode_Title_Event";
101static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
102
103bool SampleCode::TitleQ(const SkEvent& evt) {
104 return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
105}
106
107void SampleCode::TitleR(SkEvent* evt, const char title[]) {
108 SkASSERT(evt && TitleQ(*evt));
109 evt->setString(gTitleEvtName, title);
110}
111
112bool SampleCode::PrefSizeQ(const SkEvent& evt) {
113 return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
114}
115
116void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
117 SkASSERT(evt && PrefSizeQ(*evt));
118 SkScalar size[2];
119 size[0] = width;
120 size[1] = height;
121 evt->setScalars(gPrefSizeEvtName, 2, size);
122}
123
124//////////////////////////////////////////////////////////////////////////////
125
126class SampleWindow : public SkOSWindow {
reed@android.com34245c72009-11-03 04:00:48 +0000127 SkTDArray<SkViewFactory> fSamples;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128public:
129 SampleWindow(void* hwnd);
130 virtual ~SampleWindow();
131
132protected:
133 virtual void onDraw(SkCanvas* canvas);
134 virtual bool onHandleKey(SkKey key);
135 virtual bool onHandleChar(SkUnichar);
136 virtual void onSizeChange();
137
138 virtual SkCanvas* beforeChildren(SkCanvas*);
139 virtual void afterChildren(SkCanvas*);
reed@android.com6c5f6f22009-08-14 16:08:38 +0000140 virtual void beforeChild(SkView* child, SkCanvas* canvas);
141 virtual void afterChild(SkView* child, SkCanvas* canvas);
142
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 virtual bool onEvent(const SkEvent& evt);
144
145#if 0
146 virtual bool handleChar(SkUnichar uni);
147 virtual bool handleEvent(const SkEvent& evt);
148 virtual bool handleKey(SkKey key);
149 virtual bool handleKeyUp(SkKey key);
150
151 virtual bool onClick(Click* click);
152 virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
153 virtual bool onHandleKeyUp(SkKey key);
154#endif
155private:
reed@android.com34245c72009-11-03 04:00:48 +0000156 int fCurrIndex;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000157
158 SkPicture* fPicture;
159 SkGLCanvas* fGLCanvas;
160 SkPath fClipPath;
161
162 enum CanvasType {
163 kRaster_CanvasType,
164 kPicture_CanvasType,
165 kOpenGL_CanvasType
166 };
167 CanvasType fCanvasType;
168
169 bool fUseClip;
170 bool fRepeatDrawing;
171 bool fAnimating;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000172 bool fRotate;
173 bool fScale;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000174
175 int fScrollTestX, fScrollTestY;
176
177 void loadView(SkView*);
178 void updateTitle();
179 bool nextSample();
180
181 void postAnimatingEvent() {
182 if (fAnimating) {
183 SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
184 evt->post(this->getSinkID(), ANIMATING_DELAY);
185 }
186 }
187
188
189 static CanvasType cycle_canvastype(CanvasType);
190
191 typedef SkOSWindow INHERITED;
192};
193
194SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
195 static const CanvasType gCT[] = {
196 kPicture_CanvasType,
197 kOpenGL_CanvasType,
198 kRaster_CanvasType
199 };
200 return gCT[ct];
201}
202
203SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
reed@android.com6efdc472008-12-19 18:24:35 +0000204#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 init_gl((WindowRef)hwnd);
reed@android.com6efdc472008-12-19 18:24:35 +0000206#endif
207
reed@android.com8a1c16f2008-12-17 15:59:43 +0000208 fPicture = NULL;
209 fGLCanvas = NULL;
210
211 fCanvasType = kRaster_CanvasType;
212 fUseClip = false;
213 fRepeatDrawing = false;
214 fAnimating = false;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000215 fRotate = false;
216 fScale = false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217
218 fScrollTestX = fScrollTestY = 0;
219
220// this->setConfig(SkBitmap::kRGB_565_Config);
221 this->setConfig(SkBitmap::kARGB_8888_Config);
222 this->setVisibleP(true);
223
reed@android.com34245c72009-11-03 04:00:48 +0000224 {
225 const SkViewRegister* reg = SkViewRegister::Head();
226 while (reg) {
227 *fSamples.append() = reg->factory();
228 reg = reg->next();
229 }
230 }
231 fCurrIndex = 0;
232 this->loadView(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000233}
234
235SampleWindow::~SampleWindow() {
236 delete fPicture;
237 delete fGLCanvas;
238}
239
240void SampleWindow::onDraw(SkCanvas* canvas) {
241 if (fRepeatDrawing) {
242 this->inval(NULL);
243 }
244}
245
246#include "SkColorPriv.h"
247
248static void reverseRedAndBlue(const SkBitmap& bm) {
249 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
250 uint8_t* p = (uint8_t*)bm.getPixels();
251 uint8_t* stop = p + bm.getSize();
252 while (p < stop) {
253 // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
254 unsigned scale = SkAlpha255To256(p[3]);
255 unsigned r = p[2];
256 unsigned b = p[0];
257 p[0] = SkAlphaMul(r, scale);
258 p[1] = SkAlphaMul(p[1], scale);
259 p[2] = SkAlphaMul(b, scale);
260 p += 4;
261 }
262}
263
264SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
reed@android.com6efdc472008-12-19 18:24:35 +0000265#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000266#ifndef USE_OFFSCREEN
267 aglSetWindowRef(gAGLContext, NULL);
268#endif
reed@android.com6efdc472008-12-19 18:24:35 +0000269#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000270 switch (fCanvasType) {
271 case kRaster_CanvasType:
272 canvas = this->INHERITED::beforeChildren(canvas);
273 break;
274 case kPicture_CanvasType:
275 fPicture = new SkPicture;
276 canvas = fPicture->beginRecording(9999, 9999);
277 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000278#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000279 case kOpenGL_CanvasType: {
280 //SkGLCanvas::DeleteAllTextures(); // just for testing
281 SkDevice* device = canvas->getDevice();
282 const SkBitmap& bitmap = device->accessBitmap(true);
283 // first clear the raster bitmap, so we don't see any leftover bits
284 bitmap.eraseColor(0);
285 // now setup our glcanvas
286 setup_offscreen_gl(bitmap, (WindowRef)this->getHWND());
287 fGLCanvas = new SkGLCanvas;
288 fGLCanvas->setViewport(bitmap.width(), bitmap.height());
289 canvas = fGLCanvas;
290 break;
291 }
reed@android.com6efdc472008-12-19 18:24:35 +0000292#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000293 }
294
295 if (fUseClip) {
296 canvas->drawColor(0xFFFF88FF);
297 canvas->clipPath(fClipPath);
298 }
299
300 return canvas;
301}
302
303static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
304 const SkRegion& rgn) {
305 SkCanvas canvas(bm);
306 SkRegion inval(rgn);
307
308 inval.translate(r.fLeft, r.fTop);
309 canvas.clipRegion(inval);
310 canvas.drawColor(0xFFFF8080);
311}
312
313void SampleWindow::afterChildren(SkCanvas* orig) {
314 switch (fCanvasType) {
315 case kRaster_CanvasType:
316 break;
317 case kPicture_CanvasType:
reed@android.comaefd2bc2009-03-30 21:02:14 +0000318 if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000319 SkPicture* pict = new SkPicture(*fPicture);
320 fPicture->unref();
321 orig->drawPicture(*pict);
322 pict->unref();
reed@android.comaefd2bc2009-03-30 21:02:14 +0000323 } else if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000324 SkDynamicMemoryWStream ostream;
325 fPicture->serialize(&ostream);
326 fPicture->unref();
327
328 SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
329 SkPicture pict(&istream);
330 orig->drawPicture(pict);
331 } else {
332 fPicture->draw(orig);
333 fPicture->unref();
334 }
335 fPicture = NULL;
336 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000337#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000338 case kOpenGL_CanvasType:
339 glFlush();
340 delete fGLCanvas;
341 fGLCanvas = NULL;
342#ifdef USE_OFFSCREEN
343 reverseRedAndBlue(orig->getDevice()->accessBitmap(true));
344#endif
345 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000346#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000347 }
348
349// if ((fScrollTestX | fScrollTestY) != 0)
350 {
351 const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
352 int dx = fScrollTestX * 7;
353 int dy = fScrollTestY * 7;
354 SkIRect r;
355 SkRegion inval;
356
357 r.set(50, 50, 50+100, 50+100);
358 bm.scrollRect(&r, dx, dy, &inval);
359 paint_rgn(bm, r, inval);
360 }
361}
362
reed@android.com6c5f6f22009-08-14 16:08:38 +0000363void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
364 if (fScale) {
365 SkScalar scale = SK_Scalar1 * 7 / 10;
366 SkScalar cx = this->width() / 2;
367 SkScalar cy = this->height() / 2;
368 canvas->translate(cx, cy);
369 canvas->scale(scale, scale);
370 canvas->translate(-cx, -cy);
371 }
372 if (fRotate) {
373 SkScalar cx = this->width() / 2;
374 SkScalar cy = this->height() / 2;
375 canvas->translate(cx, cy);
376 canvas->rotate(SkIntToScalar(30));
377 canvas->translate(-cx, -cy);
378 }
379}
380
381void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
382}
383
reed@android.com8a1c16f2008-12-17 15:59:43 +0000384static SkBitmap::Config gConfigCycle[] = {
385 SkBitmap::kNo_Config, // none -> none
386 SkBitmap::kNo_Config, // a1 -> none
387 SkBitmap::kNo_Config, // a8 -> none
388 SkBitmap::kNo_Config, // index8 -> none
389 SkBitmap::kARGB_4444_Config, // 565 -> 4444
390 SkBitmap::kARGB_8888_Config, // 4444 -> 8888
391 SkBitmap::kRGB_565_Config // 8888 -> 565
392};
393
394static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
395 return gConfigCycle[c];
396}
397
398bool SampleWindow::nextSample() {
reed@android.com34245c72009-11-03 04:00:48 +0000399 fCurrIndex = (fCurrIndex + 1) % fSamples.count();
400 this->loadView(fSamples[fCurrIndex]());
401 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000402}
403
404bool SampleWindow::onEvent(const SkEvent& evt) {
405 if (evt.isType(ANIMATING_EVENTTYPE)) {
406 if (fAnimating) {
407 this->nextSample();
408 this->postAnimatingEvent();
409 }
410 return true;
411 }
reed@android.com34245c72009-11-03 04:00:48 +0000412 if (evt.isType("set-curr-index")) {
413 fCurrIndex = evt.getFast32() % fSamples.count();
414 this->loadView(fSamples[fCurrIndex]());
415 return true;
416 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000417 return this->INHERITED::onEvent(evt);
418}
419
reed@android.com0ae6b242008-12-23 16:49:54 +0000420static void cleanup_for_filename(SkString* name) {
421 char* str = name->writable_str();
422 for (int i = 0; i < name->size(); i++) {
423 switch (str[i]) {
424 case ':': str[i] = '-'; break;
425 case '/': str[i] = '-'; break;
426 case ' ': str[i] = '_'; break;
427 default: break;
428 }
429 }
430}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000431
432bool SampleWindow::onHandleChar(SkUnichar uni) {
433 int dx = 0xFF;
434 int dy = 0xFF;
435
436 switch (uni) {
437 case '5': dx = 0; dy = 0; break;
438 case '8': dx = 0; dy = -1; break;
439 case '6': dx = 1; dy = 0; break;
440 case '2': dx = 0; dy = 1; break;
441 case '4': dx = -1; dy = 0; break;
442 case '7': dx = -1; dy = -1; break;
443 case '9': dx = 1; dy = -1; break;
444 case '3': dx = 1; dy = 1; break;
445 case '1': dx = -1; dy = 1; break;
446
447 default:
448 break;
449 }
450
451 if (0xFF != dx && 0xFF != dy) {
452 if ((dx | dy) == 0) {
453 fScrollTestX = fScrollTestY = 0;
454 } else {
455 fScrollTestX += dx;
456 fScrollTestY += dy;
457 }
458 this->inval(NULL);
459 return true;
460 }
461
reed@android.com0ae6b242008-12-23 16:49:54 +0000462 switch (uni) {
463 case 'a':
464 fAnimating = !fAnimating;
465 this->postAnimatingEvent();
466 this->updateTitle();
467 return true;
468 case 'f': {
469 const char* title = this->getTitle();
470 if (title[0] == 0) {
471 title = "sampleapp";
472 }
473 SkString name(title);
474 cleanup_for_filename(&name);
475 name.append(".png");
476 if (SkImageEncoder::EncodeFile(name.c_str(), this->getBitmap(),
reed@android.comb08eb2b2009-01-06 20:16:26 +0000477 SkImageEncoder::kPNG_Type, 100)) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000478 SkDebugf("Created %s\n", name.c_str());
479 }
480 return true;
481 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000482 case 'r':
483 fRotate = !fRotate;
484 this->inval(NULL);
485 this->updateTitle();
486 return true;
487 case 's':
488 fScale = !fScale;
489 this->inval(NULL);
490 this->updateTitle();
491 return true;
reed@android.com0ae6b242008-12-23 16:49:54 +0000492 default:
493 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494 }
495
496 return this->INHERITED::onHandleChar(uni);
497}
498
499#include "SkDumpCanvas.h"
500
501bool SampleWindow::onHandleKey(SkKey key) {
502 switch (key) {
503 case kRight_SkKey:
504 if (this->nextSample()) {
505 return true;
506 }
507 break;
508 case kLeft_SkKey:
509 fCanvasType = cycle_canvastype(fCanvasType);
510 this->updateTitle();
511 this->inval(NULL);
512 return true;
513 case kUp_SkKey:
514 fUseClip = !fUseClip;
515 this->updateTitle();
516 this->inval(NULL);
517 return true;
518 case kDown_SkKey:
519 this->setConfig(cycle_configs(this->getBitmap().config()));
520 this->updateTitle();
521 return true;
522 case kOK_SkKey:
523 if (true) {
524 SkDebugfDumper dumper;
525 SkDumpCanvas dc(&dumper);
526 this->draw(&dc);
527 } else {
528 fRepeatDrawing = !fRepeatDrawing;
529 if (fRepeatDrawing) {
530 this->inval(NULL);
531 }
532 }
533 return true;
reed@android.com34245c72009-11-03 04:00:48 +0000534 case kBack_SkKey:
535 this->loadView(NULL);
536 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000537 default:
538 break;
539 }
540 return this->INHERITED::onHandleKey(key);
541}
542
543void SampleWindow::loadView(SkView* view) {
544 SkView::F2BIter iter(this);
545 SkView* prev = iter.next();
546 if (prev) {
547 prev->detachFromParent();
548 }
reed@android.com34245c72009-11-03 04:00:48 +0000549
550 if (NULL == view) {
551 view = create_overview(fSamples.count(), fSamples.begin());
552 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000553 view->setVisibleP(true);
554 this->attachChildToFront(view)->unref();
555 view->setSize(this->width(), this->height());
556
557 this->updateTitle();
558}
559
560static const char* gConfigNames[] = {
561 "unknown config",
562 "A1",
563 "A8",
564 "Index8",
565 "565",
566 "4444",
567 "8888"
568};
569
570static const char* configToString(SkBitmap::Config c) {
571 return gConfigNames[c];
572}
573
574static const char* gCanvasTypePrefix[] = {
575 "raster: ",
576 "picture: ",
577 "opengl: "
578};
579
580void SampleWindow::updateTitle() {
581 SkString title;
582
583 SkView::F2BIter iter(this);
584 SkView* view = iter.next();
585 SkEvent evt(gTitleEvtName);
586 if (view->doQuery(&evt)) {
587 title.set(evt.findString(gTitleEvtName));
588 }
589 if (title.size() == 0) {
590 title.set("<unknown>");
591 }
592
593 title.prepend(gCanvasTypePrefix[fCanvasType]);
594
595 title.prepend(" ");
596 title.prepend(configToString(this->getBitmap().config()));
597
598 if (fAnimating) {
599 title.prepend("<A> ");
600 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000601 if (fScale) {
602 title.prepend("<S> ");
603 }
604 if (fRotate) {
605 title.prepend("<R> ");
606 }
607
reed@android.com8a1c16f2008-12-17 15:59:43 +0000608 this->setTitle(title.c_str());
609}
610
611void SampleWindow::onSizeChange() {
612 this->INHERITED::onSizeChange();
613
614 SkView::F2BIter iter(this);
615 SkView* view = iter.next();
616 view->setSize(this->width(), this->height());
617
618 // rebuild our clippath
619 {
620 const SkScalar W = this->width();
621 const SkScalar H = this->height();
622
623 fClipPath.reset();
624#if 0
625 for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
626 SkRect r;
627 r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
628 for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
629 fClipPath.addRect(r);
630 }
631#else
632 SkRect r;
633 r.set(0, 0, W, H);
634 fClipPath.addRect(r, SkPath::kCCW_Direction);
635 r.set(W/4, H/4, W*3/4, H*3/4);
636 fClipPath.addRect(r, SkPath::kCW_Direction);
637#endif
638 }
639
640 this->updateTitle(); // to refresh our config
641}
642
643///////////////////////////////////////////////////////////////////////////////
644
645SkOSWindow* create_sk_window(void* hwnd) {
646 return new SampleWindow(hwnd);
647}
648
649void get_preferred_size(int* x, int* y, int* width, int* height) {
650 *x = 10;
651 *y = 50;
652 *width = 640;
653 *height = 480;
654}
655
656void application_init() {
657// setenv("ANDROID_ROOT", "../../../data", 0);
658 setenv("ANDROID_ROOT", "/android/device/data", 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +0000659 SkGraphics::Init();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000660 SkEvent::Init();
661}
662
663void application_term() {
664 SkEvent::Term();
665 SkGraphics::Term();
666}