11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SampleCode.h" 90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkView.h" 100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h" 110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkGraphics.h" 120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRandom.h" 130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkFlipPixelRef.h" 140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPageFlipper.h" 150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include <pthread.h> 170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define WIDTH 160 190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define HEIGHT 200 200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic bool gDone; 220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void bounce(SkScalar* x, SkScalar* dx, const int max) { 240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *x += *dx; 250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (*x < 0) { 260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *x = 0; 270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (*dx < 0) { 280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *dx = -*dx; 290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } else if (*x > SkIntToScalar(max)) { 310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *x = SkIntToScalar(max); 320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (*dx > 0) { 330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *dx = -*dx; 340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void* draw_proc(void* context) { 390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const int OVALW = 32; 400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const int OVALH = 32; 410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const SkBitmap* bm = static_cast<const SkBitmap*>(context); 430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFlipPixelRef* ref = static_cast<SkFlipPixelRef*>(bm->pixelRef()); 440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const int DSCALE = 1; 460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar dx = SkIntToScalar(7) / DSCALE; 470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar dy = SkIntToScalar(5) / DSCALE; 480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar x = 0; 490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar y = 0; 500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPaint paint; 520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAntiAlias(true); 540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setColor(SK_ColorRED); 550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRect oval; 570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger oval.setEmpty(); 580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRect clipR = SkRect::MakeWH(SkIntToScalar(bm->width()), SkIntToScalar(bm->height())); 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clipR.inset(SK_Scalar1/4, SK_Scalar1/4); 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger while (!gDone) { 630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger ref->inval(oval, true); 640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger oval.set(x, y, x + SkIntToScalar(OVALW), y + SkIntToScalar(OVALH)); 650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger ref->inval(oval, true); 660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkAutoFlipUpdate update(ref); 680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (!update.dirty().isEmpty()) { 700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // this must be local to the loop, since it needs to forget the pixels 710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // its writing to after each iteration, since we do the swap 720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkCanvas canvas(update.bitmap()); 730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas.clipRegion(update.dirty()); 740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas.drawColor(0, SkXfermode::kClear_Mode); 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas.clipRect(clipR, SkRegion::kIntersect_Op, true); 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas.drawOval(oval, paint); 780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounce(&x, &dx, WIDTH-OVALW); 800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounce(&y, &dy, HEIGHT-OVALH); 810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return NULL; 830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic const SkBitmap::Config gConfigs[] = { 860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkBitmap::kARGB_8888_Config, 870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkBitmap::kRGB_565_Config, 880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkBitmap::kARGB_4444_Config, 890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkBitmap::kA8_Config 900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass PageFlipView : public SampleView { 930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic: 940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger enum { N = SK_ARRAY_COUNT(gConfigs) }; 960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger pthread_t fThreads[N]; 980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkBitmap fBitmaps[N]; 990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger PageFlipView() { 1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger gDone = false; 1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < N; i++) { 1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int status; 1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger pthread_attr_t attr; 1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger status = pthread_attr_init(&attr); 1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(0 == status); 1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBitmaps[i].setConfig(gConfigs[i], WIDTH, HEIGHT); 1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFlipPixelRef* pr = new SkFlipPixelRef(gConfigs[i], WIDTH, HEIGHT); 1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBitmaps[i].setPixelRef(pr)->unref(); 1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBitmaps[i].eraseColor(0); 1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger status = pthread_create(&fThreads[i], &attr, draw_proc, &fBitmaps[i]); 1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(0 == status); 1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setBGColor(0xFFDDDDDD); 1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual ~PageFlipView() { 1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger gDone = true; 1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < N; i++) { 1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger void* ret; 1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int status = pthread_join(fThreads[i], &ret); 1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(0 == status); 1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected: 1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // overrides from SkEventSink 1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual bool onQuery(SkEvent* evt) { 1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SampleCode::TitleQ(*evt)) { 1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SampleCode::TitleR(evt, "PageFlip"); 1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onQuery(evt); 1370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual void onDrawContent(SkCanvas* canvas) { 1400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar x = SkIntToScalar(10); 1410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar y = SkIntToScalar(10); 1420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < N; i++) { 1430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawBitmap(fBitmaps[i], x, y); 1440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger x += SkIntToScalar(fBitmaps[i].width() + 20); 1450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 1470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 1500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 1510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onFindClickHandler(x, y); 1520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual bool onClick(Click* click) { 1550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onClick(click); 1560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate: 1590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger typedef SampleView INHERITED; 1600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger////////////////////////////////////////////////////////////////////////////// 1630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkView* MyFactory() { return new PageFlipView; } 1650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkViewRegister reg(MyFactory); 1660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 167