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