|  | 
 | /* | 
 |  * Copyright 2011 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 | #include "SampleCode.h" | 
 | #include "SkView.h" | 
 | #include "SkCanvas.h" | 
 | #include "SkGraphics.h" | 
 | #include "SkRandom.h" | 
 | #include "SkFlipPixelRef.h" | 
 | #include "SkPageFlipper.h" | 
 |  | 
 | #include <pthread.h> | 
 |  | 
 | #define WIDTH   160 | 
 | #define HEIGHT  200 | 
 |  | 
 | static bool gDone; | 
 |  | 
 | static void bounce(SkScalar* x, SkScalar* dx, const int max) { | 
 |     *x += *dx; | 
 |     if (*x < 0) { | 
 |         *x = 0; | 
 |         if (*dx < 0) { | 
 |             *dx = -*dx; | 
 |         } | 
 |     } else if (*x > SkIntToScalar(max)) { | 
 |         *x = SkIntToScalar(max); | 
 |         if (*dx > 0) { | 
 |             *dx = -*dx; | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | static void* draw_proc(void* context) { | 
 |     const int OVALW = 32; | 
 |     const int OVALH = 32; | 
 |  | 
 |     const SkBitmap* bm = static_cast<const SkBitmap*>(context); | 
 |     SkFlipPixelRef* ref = static_cast<SkFlipPixelRef*>(bm->pixelRef()); | 
 |  | 
 |     const int DSCALE = 1; | 
 |     SkScalar    dx = SkIntToScalar(7) / DSCALE; | 
 |     SkScalar    dy = SkIntToScalar(5) / DSCALE; | 
 |     SkScalar    x = 0; | 
 |     SkScalar    y = 0; | 
 |  | 
 |     SkPaint paint; | 
 |      | 
 |     paint.setAntiAlias(true); | 
 |     paint.setColor(SK_ColorRED); | 
 |      | 
 |     SkRect oval; | 
 |     oval.setEmpty(); | 
 |  | 
 |     SkRect clipR = SkRect::MakeWH(SkIntToScalar(bm->width()), SkIntToScalar(bm->height())); | 
 |     clipR.inset(SK_Scalar1/4, SK_Scalar1/4); | 
 |                                    | 
 |     while (!gDone) { | 
 |         ref->inval(oval, true); | 
 |         oval.set(x, y, x + SkIntToScalar(OVALW), y + SkIntToScalar(OVALH)); | 
 |         ref->inval(oval, true); | 
 |  | 
 |         SkAutoFlipUpdate    update(ref); | 
 |          | 
 |         if (!update.dirty().isEmpty()) { | 
 |             // this must be local to the loop, since it needs to forget the pixels | 
 |             // its writing to after each iteration, since we do the swap | 
 |             SkCanvas    canvas(update.bitmap()); | 
 |             canvas.clipRegion(update.dirty()); | 
 |             canvas.drawColor(0, SkXfermode::kClear_Mode);             | 
 |             canvas.clipRect(clipR, SkRegion::kIntersect_Op, true); | 
 |              | 
 |             canvas.drawOval(oval, paint); | 
 |         } | 
 |         bounce(&x, &dx, WIDTH-OVALW); | 
 |         bounce(&y, &dy, HEIGHT-OVALH); | 
 |     } | 
 |     return NULL; | 
 | } | 
 |  | 
 | static const SkBitmap::Config gConfigs[] = { | 
 |     SkBitmap::kARGB_8888_Config, | 
 |     SkBitmap::kRGB_565_Config, | 
 |     SkBitmap::kARGB_4444_Config, | 
 |     SkBitmap::kA8_Config | 
 | }; | 
 |  | 
 | class PageFlipView : public SampleView { | 
 | public: | 
 |      | 
 |     enum { N = SK_ARRAY_COUNT(gConfigs) }; | 
 |      | 
 |     pthread_t   fThreads[N]; | 
 |     SkBitmap    fBitmaps[N]; | 
 |  | 
 | 	PageFlipView() { | 
 |         gDone = false; | 
 |         for (int i = 0; i < N; i++) { | 
 |             int             status; | 
 |             pthread_attr_t  attr; | 
 |              | 
 |             status = pthread_attr_init(&attr); | 
 |             SkASSERT(0 == status); | 
 |  | 
 |             fBitmaps[i].setConfig(gConfigs[i], WIDTH, HEIGHT); | 
 |             SkFlipPixelRef* pr = new SkFlipPixelRef(gConfigs[i], WIDTH, HEIGHT); | 
 |             fBitmaps[i].setPixelRef(pr)->unref(); | 
 |             fBitmaps[i].eraseColor(0); | 
 |  | 
 |             status = pthread_create(&fThreads[i], &attr,  draw_proc, &fBitmaps[i]); | 
 |             SkASSERT(0 == status); | 
 |         } | 
 |         this->setBGColor(0xFFDDDDDD); | 
 |     } | 
 |      | 
 |     virtual ~PageFlipView() { | 
 |         gDone = true; | 
 |         for (int i = 0; i < N; i++) { | 
 |             void* ret; | 
 |             int status = pthread_join(fThreads[i], &ret); | 
 |             SkASSERT(0 == status); | 
 |         } | 
 |     } | 
 |      | 
 | protected: | 
 |     // overrides from SkEventSink | 
 |     virtual bool onQuery(SkEvent* evt) { | 
 |         if (SampleCode::TitleQ(*evt)) { | 
 |             SampleCode::TitleR(evt, "PageFlip"); | 
 |             return true; | 
 |         } | 
 |         return this->INHERITED::onQuery(evt); | 
 |     } | 
 |  | 
 |     virtual void onDrawContent(SkCanvas* canvas) { | 
 |         SkScalar x = SkIntToScalar(10); | 
 |         SkScalar y = SkIntToScalar(10); | 
 |         for (int i = 0; i < N; i++) { | 
 |             canvas->drawBitmap(fBitmaps[i], x, y); | 
 |             x += SkIntToScalar(fBitmaps[i].width() + 20); | 
 |         } | 
 |         this->inval(NULL); | 
 |     } | 
 |      | 
 |     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { | 
 |         this->inval(NULL); | 
 |         return this->INHERITED::onFindClickHandler(x, y); | 
 |     } | 
 |      | 
 |     virtual bool onClick(Click* click) { | 
 |         return this->INHERITED::onClick(click); | 
 |     } | 
 |      | 
 | private: | 
 |     typedef SampleView INHERITED; | 
 | }; | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | static SkView* MyFactory() { return new PageFlipView; } | 
 | static SkViewRegister reg(MyFactory); | 
 |  |