1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7868074b50b0fc3e460d2aa97c1096827fe0a1935reed
82c8208f3a444098aee562f5a1ef620142807eda2Scroggo#include "SampleApp.h"
92c8208f3a444098aee562f5a1ef620142807eda2Scroggo
10bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "OverView.h"
11bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SampleCode.h"
12bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SamplePipeControllers.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
14bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkCommandLineFlags.h"
15bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkData.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDevice.h"
17bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkGPipe.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
19b08eb2b3bce45411494fe00258e4c91248ccd15ereed@android.com#include "SkImageEncoder.h"
20bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkOSFile.h"
21bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkPDFDevice.h"
22bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkPDFDocument.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h"
25770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
279a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org#include "SkSurface.h"
28f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com#include "SkTSort.h"
294417740a480786ca65379ba5b398c500ba34ee18reed@android.com#include "SkTime.h"
300f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo#include "SkTypeface.h"
31bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "SkWindow.h"
32bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "TransitionView.h"
33bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "sk_tool_utils.h"
34f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
35cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
366bf38b59c9de1cd35cd091cf8766117f4e1f66a0tomhudson@google.com#include "gl/GrGLInterface.h"
379c1f1ac5d399c73f5f331bdf7b392ea7f0c44dafbsalomon@google.com#include "gl/GrGLUtil.h"
38583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.com#include "GrRenderTarget.h"
39cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "GrContext.h"
40cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
41cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
42cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GrContext;
43cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
442c8208f3a444098aee562f5a1ef620142807eda2Scroggo
451830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comextern SampleView* CreateSamplePictFileView(const char filename[]);
461830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
471830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comclass PictFileFactory : public SkViewFactory {
481830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    SkString fFilename;
491830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.compublic:
501830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    PictFileFactory(const SkString& filename) : fFilename(filename) {}
511830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    virtual SkView* operator() () const SK_OVERRIDE {
521830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        return CreateSamplePictFileView(fFilename.c_str());
531830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    }
541830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com};
551830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
56f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com#ifdef SAMPLE_PDF_FILE_VIEWER
57f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.comextern SampleView* CreateSamplePdfFileViewer(const char filename[]);
58f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com
59f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.comclass PdfFileViewerFactory : public SkViewFactory {
60f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    SkString fFilename;
61f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.compublic:
62f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    PdfFileViewerFactory(const SkString& filename) : fFilename(filename) {}
63f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    virtual SkView* operator() () const SK_OVERRIDE {
64f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com        return CreateSamplePdfFileViewer(fFilename.c_str());
65f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    }
66f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com};
67f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com#endif  // SAMPLE_PDF_FILE_VIEWER
68f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com
69db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#define PIPE_FILEx
70db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_FILE
711f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#define FILE_PATH "/path/to/drawing.data"
721f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#endif
731f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com
74f121b0525485fb18e96c4b9dbc57594c430e42f4yangsu@google.com#define PIPE_NETx
75db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_NET
76db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkSockets.h"
77db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comSkTCPServer gServer;
78db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
79ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
80628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#define USE_ARROWS_FOR_ZOOM true
81b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
82b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
83b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com//#define DEFAULT_TO_ANGLE 1
84b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#else
8582d1223aece4703bc9f3a3612cbabaa8c2f2809bbsalomon@google.com#define DEFAULT_TO_GPU 0 // if 1 default rendering is on GPU
86b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
87f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ANIMATING_EVENTTYPE "nextSample"
8984cfce14fec1f963fedaa3c81b8f3faccd3db13areed@google.com#define ANIMATING_DELAY     250
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
912eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#ifdef SK_DEBUG
92bad8c87812234117d3dc411382fca60e2e868477reed@google.com    #define FPS_REPEAT_MULTIPLIER   1
932eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#else
94bad8c87812234117d3dc411382fca60e2e868477reed@google.com    #define FPS_REPEAT_MULTIPLIER   10
952eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#endif
96bad8c87812234117d3dc411382fca60e2e868477reed@google.com#define FPS_REPEAT_COUNT    (10 * FPS_REPEAT_MULTIPLIER)
972eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
983cec4d71e6f53fda99705427f9820d025cfbf64breed@google.comstatic SampleWindow* gSampleWindow;
993cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com
100a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.comstatic bool gShowGMBounds;
101a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com
1026de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.orgstatic void post_event_to_sink(SkEvent* evt, SkEventSink* sink) {
1032072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    evt->setTargetID(sink->getSinkID())->post();
1042072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com}
1052072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com
1066f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
1076f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1086f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* skip_until(const char* str, const char* skip) {
1096f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!str) {
1106f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return NULL;
1116f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1126f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return strstr(str, skip);
1136f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1146f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1156f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* skip_past(const char* str, const char* skip) {
1166f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* found = skip_until(str, skip);
1176f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!found) {
1186f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return NULL;
1196f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1206f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return found + strlen(skip);
1216f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1226f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1236f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* gPrefFileName = "sampleapp_prefs.txt";
1246f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1256fc7cc23a9c33960b879f69d92d6fb0e1373e556epoger@google.comstatic bool readTitleFromPrefs(SkString* title) {
1266f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkFILEStream stream(gPrefFileName);
1276f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!stream.isValid()) {
1286f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return false;
1296f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1306f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1317fa2a65c0cfc714364490cb715171461143024e0reed@google.com    size_t len = stream.getLength();
1326f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString data(len);
1336f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    stream.read(data.writable_str(), len);
1346f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* s = data.c_str();
1356f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1366f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "curr-slide-title");
1376f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "=");
1386f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "\"");
1396f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* stop = skip_until(s, "\"");
1406f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (stop > s) {
1416f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        title->set(s, stop - s);
1426f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return true;
1436f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1446f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return false;
1456f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1466f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1476fc7cc23a9c33960b879f69d92d6fb0e1373e556epoger@google.comstatic void writeTitleToPrefs(const char* title) {
1486f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkFILEWStream stream(gPrefFileName);
1496f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString data;
1506f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    data.printf("curr-slide-title = \"%s\"\n", title);
1516f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    stream.write(data.c_str(), data.size());
1526f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1536f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1546f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
1556f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
156098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comclass SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager {
157098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.compublic:
158098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
159cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    DefaultDeviceManager() {
160cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
161cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurContext = NULL;
162cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurIntf = NULL;
163cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurRenderTarget = NULL;
164cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fMSAASampleCount = 0;
165cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
166cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fBackend = kNone_BackEndType;
167098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
168098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
169098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual ~DefaultDeviceManager() {
170cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
171b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurContext);
172b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurIntf);
173b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurRenderTarget);
174cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
175098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
176098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
1771195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) {
178b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(kNone_BackEndType == fBackend);
179b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
180b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fBackend = kNone_BackEndType;
181d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
182cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
183b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        switch (win->getDeviceType()) {
184b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kRaster_DeviceType:
185b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
186b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kPicture_DeviceType:
187b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
188b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kGPU_DeviceType:
189b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
190b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kNullGPU_DeviceType:
191b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // all these guys use the native backend
192b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fBackend = kNativeGL_BackEndType;
193b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
194d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
195b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kANGLE_DeviceType:
196b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // ANGLE is really the only odd man out
197b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fBackend = kANGLE_BackEndType;
198b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
199cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
200b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            default:
201b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                SkASSERT(false);
202b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
203d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        }
20464cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        AttachmentInfo attachmentInfo;
20564cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com        bool result = win->attach(fBackend, msaaSampleCount, &attachmentInfo);
206d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        if (!result) {
20774913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com            SkDebugf("Failed to initialize GL");
208b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            return;
209098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
2101195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fMSAASampleCount = msaaSampleCount;
211b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
212b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(NULL == fCurIntf);
213d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org        SkAutoTUnref<const GrGLInterface> glInterface;
214b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        switch (win->getDeviceType()) {
215b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kRaster_DeviceType:
216b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
217b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kPicture_DeviceType:
218b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
219b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kGPU_DeviceType:
220b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // all these guys use the native interface
221d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org                glInterface.reset(GrGLCreateNativeInterface());
222b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
223d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
224b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kANGLE_DeviceType:
225d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org                glInterface.reset(GrGLCreateANGLEInterface());
226b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
227cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
228b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kNullGPU_DeviceType:
229d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org                glInterface.reset(GrGLCreateNullInterface());
230b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
231b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            default:
232b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                SkASSERT(false);
233b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
2346fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        }
235b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
236d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org        // Currently SampleApp does not use NVPR. TODO: Provide an NVPR device type that is skipped
237d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org        // when the driver doesn't support NVPR.
238d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org        fCurIntf = GrGLInterfaceRemoveNVPR(glInterface.get());
239d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org
240b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(NULL == fCurContext);
24116e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com        fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
242b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
243b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (NULL == fCurContext || NULL == fCurIntf) {
244b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            // We need some context and interface to see results
245b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurContext);
246b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurIntf);
247d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org            fCurContext = NULL;
248d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org            fCurIntf = NULL;
249098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkDebugf("Failed to setup 3D");
250b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
251b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            win->detach();
25274913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        }
253cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
254b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        // call windowSizeChanged to create the render target
255cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        this->windowSizeChanged(win);
256098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
257098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
258b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    virtual void tearDownBackend(SampleWindow *win) {
259cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
260b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurContext);
261b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurContext = NULL;
262b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
263b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurIntf);
264b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurIntf = NULL;
265b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
266b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurRenderTarget);
267b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurRenderTarget = NULL;
268cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
269ddd40e5e96c43ff6730745b53abf09bf0129f6d2bsalomon@google.com        win->detach();
270ddd40e5e96c43ff6730745b53abf09bf0129f6d2bsalomon@google.com        fBackend = kNone_BackEndType;
271098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
272098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
2735957f47e8de0ff55b8c0bf84984d4915c7c72825reed@google.com    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
2745957f47e8de0ff55b8c0bf84984d4915c7c72825reed@google.com                                   SampleWindow* win) {
275cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
27682502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        if (IsGpuDeviceType(dType) && NULL != fCurContext) {
2771f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com            SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fCurContext, fCurRenderTarget));
27882502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            return new SkCanvas(device);
27982502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        } else
280cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
28182502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        {
28282502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            return NULL;
283098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
284098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
285098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
286098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual void publishCanvas(SampleWindow::DeviceType dType,
287098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                               SkCanvas* canvas,
288098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                               SampleWindow* win) {
289cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
290b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (fCurContext) {
291098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            // in case we have queued drawing calls
292b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            fCurContext->flush();
293b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
29482502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            if (!IsGpuDeviceType(dType)) {
295098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                // need to send the raster bits to the (gpu) window
296b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurContext->setRenderTarget(fCurRenderTarget);
297098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                const SkBitmap& bm = win->getBitmap();
298b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
299fb6fefed0976d7fed193155900a186dc880451b6commit-bot@chromium.org                                             SkImageInfo2GrPixelConfig(bm.colorType(),
300fb6fefed0976d7fed193155900a186dc880451b6commit-bot@chromium.org                                                                       bm.alphaType()),
3016f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                             bm.getPixels(),
3026f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                             bm.rowBytes());
303098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            }
304098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
305cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
306b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
307b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        win->present();
308098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
309098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
310098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual void windowSizeChanged(SampleWindow* win) {
311cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
312b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (fCurContext) {
31364cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            AttachmentInfo attachmentInfo;
31464cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            win->attach(fBackend, fMSAASampleCount, &attachmentInfo);
315098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
31616e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com            GrBackendRenderTargetDesc desc;
317e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com            desc.fWidth = SkScalarRoundToInt(win->width());
318e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com            desc.fHeight = SkScalarRoundToInt(win->height());
319fec0bc3fc13481f5bcb341ab2d2d695911f39bd4bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
3203cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org            desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
32164cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            desc.fSampleCnt = attachmentInfo.fSampleCount;
32264cc810ad165724f9c666a75bd52e41c67f13564bsalomon@google.com            desc.fStencilBits = attachmentInfo.fStencilBits;
323098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            GrGLint buffer;
324b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
325e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com            desc.fRenderTargetHandle = buffer;
326098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
327b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurRenderTarget);
32816e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com            fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
32974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        }
330cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
331098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
332098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
333b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    virtual GrContext* getGrContext() {
334cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
335b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        return fCurContext;
336cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
337cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        return NULL;
338cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
339098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
3401195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
3411195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
342cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3431195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return fCurRenderTarget;
344cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
345cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        return NULL;
346cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
3471195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
3481195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
349098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comprivate:
350cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
351cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
352b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    GrContext*              fCurContext;
353b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    const GrGLInterface*    fCurIntf;
354b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    GrRenderTarget*         fCurRenderTarget;
355cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    int fMSAASampleCount;
356cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
357b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
358b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    SkOSWindow::SkBackEndTypes fBackend;
359b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
360b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    typedef SampleWindow::DeviceManager INHERITED;
361098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com};
362098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
363098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com///////////////
3642eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic const char view_inval_msg[] = "view-inval-msg";
3652eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
36662b65b0913566381db468277de07e5dd2a9237caScroggovoid SampleWindow::postInvalDelay() {
36787fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    (new SkEvent(view_inval_msg, this->getSinkID()))->postDelay(1);
3682eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
3692eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
3702eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic bool isInvalEvent(const SkEvent& evt) {
3712eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return evt.isType(view_inval_msg);
3722eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
3732eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org//////////////////
3742eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
37548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func)
37648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    : fCreateFunc(func) {
37748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
37848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
3798301de132eb016f56450017c0000f9b5d913809dbsalomon@google.comSkView* SkFuncViewFactory::operator() () const {
38048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    return (*fCreateFunc)();
38148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
38248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
38348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com#include "GMSampleView.h"
38448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
38548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func)
38648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    : fFunc(func) {
38748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
38848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
38948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkView* SkGMSampleViewFactory::operator() () const {
390b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org    skiagm::GM* gm = fFunc(NULL);
391b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org    gm->setMode(skiagm::GM::kSample_Mode);
392b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org    return new GMSampleView(gm);
39348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
39448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkViewRegister* SkViewRegister::gHead;
39648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) {
39748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact->ref();
39848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
39948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
40048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
40148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
40248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(SkViewCreateFunc func) {
40348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact = new SkFuncViewFactory(func);
40448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
40548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
40648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
40748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
40848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(GMFactoryFunc func) {
40948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact = new SkGMSampleViewFactory(func);
41048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
41148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
41248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
41348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
41448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comclass AutoUnrefArray {
41548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.compublic:
41648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    AutoUnrefArray() {}
41748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    ~AutoUnrefArray() {
41848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        int count = fObjs.count();
41948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        for (int i = 0; i < count; ++i) {
42048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            fObjs[i]->unref();
42148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        }
42248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    }
42348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    SkRefCnt*& push_back() { return *fObjs.append(); }
4244605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
42548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comprivate:
42648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    SkTDArray<SkRefCnt*> fObjs;
42748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com};
42848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
42948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// registers GMs as Samples
43048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// This can't be performed during static initialization because it could be
43148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// run before GMRegistry has been fully built.
43202939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comstatic void SkGMRegistyToSampleRegistry() {
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool gOnce;
4344605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    static AutoUnrefArray fRegisters;
43548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
43748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head();
43848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        while (gmreg) {
43948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            fRegisters.push_back() = new SkViewRegister(gmreg->factory());
44048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            gmreg = gmreg->next();
44148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        }
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
446f0b5f68807cfa18cce0647d275778147901945cdreed@google.com//////////////////////////////////////////////////////////////////////////////
447f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
448569e0435af62bdb88a662fa0592f75673a17afd9reed@google.comenum FlipAxisEnum {
449569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    kFlipAxis_X = (1 << 0),
450569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    kFlipAxis_Y = (1 << 1)
451569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com};
452f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
453569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com#include "SkDrawFilter.h"
454569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
45596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.comstruct HintingState {
45696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    SkPaint::Hinting hinting;
45796aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    const char* name;
45896aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    const char* label;
45996aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com};
46096aabc850835f6d08a117c0277be93848ddbf785bungeman@google.comstatic HintingState gHintingStates[] = {
46196aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    {SkPaint::kNo_Hinting, "Mixed", NULL },
46296aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    {SkPaint::kNo_Hinting, "None", "H0 " },
46396aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    {SkPaint::kSlight_Hinting, "Slight", "Hs " },
46496aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    {SkPaint::kNormal_Hinting, "Normal", "Hn " },
46596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    {SkPaint::kFull_Hinting, "Full", "Hf " },
46696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com};
46796aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com
46815bc13d20fe79914c7128881e45064becd11bc9dreed@google.comstruct FilterLevelState {
46915bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    SkPaint::FilterLevel    fLevel;
47015bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    const char*             fName;
47115bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    const char*             fLabel;
47215bc13d20fe79914c7128881e45064becd11bc9dreed@google.com};
47315bc13d20fe79914c7128881e45064becd11bc9dreed@google.comstatic FilterLevelState gFilterLevelStates[] = {
47415bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    { SkPaint::kNone_FilterLevel,   "Mixed",    NULL    },
47515bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    { SkPaint::kNone_FilterLevel,   "None",     "F0 "   },
47615bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    { SkPaint::kLow_FilterLevel,    "Low",      "F1 "   },
47715bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    { SkPaint::kMedium_FilterLevel, "Medium",   "F2 "   },
47815bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    { SkPaint::kHigh_FilterLevel,   "High",     "F3 "   },
47915bc13d20fe79914c7128881e45064becd11bc9dreed@google.com};
48015bc13d20fe79914c7128881e45064becd11bc9dreed@google.com
481569e0435af62bdb88a662fa0592f75673a17afd9reed@google.comclass FlagsDrawFilter : public SkDrawFilter {
482569e0435af62bdb88a662fa0592f75673a17afd9reed@google.compublic:
48315bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    FlagsDrawFilter(SkOSMenu::TriState lcd, SkOSMenu::TriState aa,
48415bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                    SkOSMenu::TriState subpixel, int hinting, int filterlevel)
48515bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        : fLCDState(lcd)
48615bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        , fAAState(aa)
48715bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        , fSubpixelState(subpixel)
48815bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        , fHintingState(hinting)
48915bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        , fFilterLevelIndex(filterlevel)
49015bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    {
49115bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        SkASSERT((unsigned)filterlevel < SK_ARRAY_COUNT(gFilterLevelStates));
49215bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    }
493f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
494971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com    virtual bool filter(SkPaint* paint, Type t) {
495db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) {
496db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
497569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        }
498db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (SkOSMenu::kMixedState != fAAState) {
499db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setAntiAlias(SkOSMenu::kOnState == fAAState);
500f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        }
50115bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        if (0 != fFilterLevelIndex) {
50215bc13d20fe79914c7128881e45064becd11bc9dreed@google.com            paint->setFilterLevel(gFilterLevelStates[fFilterLevelIndex].fLevel);
503176753aa6d695ebcb76c0f82265ad69dc41dc593reed@google.com        }
50496aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com        if (SkOSMenu::kMixedState != fSubpixelState) {
50596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com            paint->setSubpixelText(SkOSMenu::kOnState == fSubpixelState);
50696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com        }
507055aa52b2d450f41d0488bd50797d6e88d02852ebungeman@google.com        if (0 != fHintingState && fHintingState < (int)SK_ARRAY_COUNT(gHintingStates)) {
50896aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com            paint->setHinting(gHintingStates[fHintingState].hinting);
50909e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com        }
510971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com        return true;
511f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
512f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
513f0b5f68807cfa18cce0647d275778147901945cdreed@google.comprivate:
514db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fLCDState;
515db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fAAState;
51696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    SkOSMenu::TriState  fSubpixelState;
51796aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    int fHintingState;
51815bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    int fFilterLevelIndex;
519f0b5f68807cfa18cce0647d275778147901945cdreed@google.com};
520f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
523dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org#define MAX_ZOOM_LEVEL  8
524dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org#define MIN_ZOOM_LEVEL  -8
525dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
526f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gCharEvtName[] = "SampleCode_Char_Event";
527f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gKeyEvtName[] = "SampleCode_Key_Event";
5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gTitleEvtName[] = "SampleCode_Title_Event";
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
530f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gFastTextEvtName[] = "SampleCode_FastText_Event";
5312072db89016c4e53a648f4d4cec08b1d6be8558creed@google.comstatic const char gUpdateWindowTitleEvtName[] = "SampleCode_UpdateWindowTitle";
532f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
533f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
534f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
535f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outUni) {
536f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outUni = evt.getFast32();
537f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
538f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
539f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
540f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
541f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
542f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
543f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
544f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
545f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outKey) {
546f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outKey = (SkKey)evt.getFast32();
547f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
548f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
549f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
550f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
551f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::TitleQ(const SkEvent& evt) {
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::TitleR(SkEvent* evt, const char title[]) {
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && TitleQ(*evt));
5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setString(gTitleEvtName, title);
5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
562db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.combool SampleCode::RequestTitle(SkView* view, SkString* title) {
563db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkEvent evt(gTitleEvtName);
564db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (view->doQuery(&evt)) {
565db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        title->set(evt.findString(gTitleEvtName));
566db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
567db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
568db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    return false;
569db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
570db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::PrefSizeQ(const SkEvent& evt) {
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && PrefSizeQ(*evt));
5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar size[2];
5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[0] = width;
5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[1] = height;
5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setScalars(gPrefSizeEvtName, 2, size);
5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
583f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::FastTextQ(const SkEvent& evt) {
584f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
585f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
586f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
587f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com///////////////////////////////////////////////////////////////////////////////
588f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5894417740a480786ca65379ba5b398c500ba34ee18reed@android.comstatic SkMSec gAnimTime;
590f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkMSec gAnimTimePrev;
591f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5924417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkMSec SampleCode::GetAnimTime() { return gAnimTime; }
593f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
594f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkScalar SampleCode::GetAnimSecondsDelta() {
595f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
596f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
5974417740a480786ca65379ba5b398c500ba34ee18reed@android.com
5984417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
599f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // since gAnimTime can be up to 32 bits, we can't convert it to a float
600f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // or we'll lose the low bits. Hence we use doubles for the intermediate
601f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // calculations
602f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double seconds = (double)gAnimTime / 1000.0;
603f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double value = SkScalarToDouble(speed) * seconds;
6044417740a480786ca65379ba5b398c500ba34ee18reed@android.com    if (period) {
605f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        value = ::fmod(value, SkScalarToDouble(period));
6064417740a480786ca65379ba5b398c500ba34ee18reed@android.com    }
607f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(value);
6084417740a480786ca65379ba5b398c500ba34ee18reed@android.com}
6094417740a480786ca65379ba5b398c500ba34ee18reed@android.com
6108500322537c5158a4632be6805b0c4210a20558bbsalomon@google.comSkScalar SampleCode::GetAnimSinScalar(SkScalar amplitude,
6118500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com                                      SkScalar periodInSec,
6128500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com                                      SkScalar phaseInSec) {
6138500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    if (!periodInSec) {
6148500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com        return 0;
6158500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    }
6168500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    double t = (double)gAnimTime / 1000.0 + phaseInSec;
6178500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    t *= SkScalarToFloat(2 * SK_ScalarPI) / periodInSec;
6188500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    amplitude = SK_ScalarHalf * amplitude;
6198500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    return SkScalarMul(amplitude, SkDoubleToScalar(sin(t))) + amplitude;
6208500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com}
6218500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com
622cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.orgenum TilingMode {
623cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kNo_Tiling,
624cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kAbs_128x128_Tiling,
625cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kAbs_256x256_Tiling,
626cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kRel_4x4_Tiling,
627cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kRel_1x16_Tiling,
628cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kRel_16x1_Tiling,
629cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
630cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    kLast_TilingMode_Enum
631cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org};
632cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
633cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.orgstruct TilingInfo {
634cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    const char* label;
635cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    SkScalar    w, h;
636cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org};
637cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
638bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.orgstatic const struct TilingInfo gTilingInfo[] = {
639cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "No tiling", SK_Scalar1        , SK_Scalar1         }, // kNo_Tiling
640cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "128x128"  , SkIntToScalar(128), SkIntToScalar(128) }, // kAbs_128x128_Tiling
641cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "256x256"  , SkIntToScalar(256), SkIntToScalar(256) }, // kAbs_256x256_Tiling
642cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "1/4x1/4"  , SK_Scalar1 / 4    , SK_Scalar1 / 4     }, // kRel_4x4_Tiling
643cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "1/1x1/16" , SK_Scalar1        , SK_Scalar1 / 16    }, // kRel_1x16_Tiling
644cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    { "1/16x1/1" , SK_Scalar1 / 16   , SK_Scalar1         }, // kRel_16x1_Tiling
645cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org};
646cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.orgSK_COMPILE_ASSERT((SK_ARRAY_COUNT(gTilingInfo) == kLast_TilingMode_Enum),
647cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                  Incomplete_tiling_labels);
648cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
649bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.orgSkSize SampleWindow::tileSize() const {
650bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    SkASSERT((TilingMode)fTilingMode < kLast_TilingMode_Enum);
651bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    const struct TilingInfo* info = gTilingInfo + fTilingMode;
652bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    return SkSize::Make(info->w > SK_Scalar1 ? info->w : this->width() * info->w,
653bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org                        info->h > SK_Scalar1 ? info->h : this->height() * info->h);
654bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org}
655cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
656cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
657f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkView* curr_view(SkWindow* wind) {
658f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkView::F2BIter iter(wind);
659f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return iter.next();
660f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
661f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
6626f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic bool curr_title(SkWindow* wind, SkString* title) {
6636f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkView* view = curr_view(wind);
6646f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (view) {
6656f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        SkEvent evt(gTitleEvtName);
6666f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        if (view->doQuery(&evt)) {
6676f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            title->set(evt.findString(gTitleEvtName));
6686f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            return true;
6696f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
6706f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
6716f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return false;
6726f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
6736f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
6742c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::setZoomCenter(float x, float y)
6752c8208f3a444098aee562f5a1ef620142807eda2Scroggo{
6764b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    fZoomCenterX = x;
6774b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    fZoomCenterY = y;
6782c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6800f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggobool SampleWindow::zoomIn()
6810f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6820f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    // Arbitrarily decided
6830f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fFatBitsScale == 25) return false;
6840f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fFatBitsScale++;
6850f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    this->inval(NULL);
6860f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    return true;
6870f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
6880f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
6890f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggobool SampleWindow::zoomOut()
6900f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6910f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fFatBitsScale == 1) return false;
6920f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fFatBitsScale--;
6930f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    this->inval(NULL);
6940f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    return true;
6950f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
6960f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
6970f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggovoid SampleWindow::updatePointer(int x, int y)
6980f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6990f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseX = x;
7000f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseY = y;
7010f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fShowZoomer) {
7020f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        this->inval(NULL);
7030f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
7040f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
7050f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
706098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comstatic inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType ct) {
707098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    static const SampleWindow::DeviceType gCT[] = {
708098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kPicture_DeviceType,
709cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
710098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kGPU_DeviceType,
711b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
712b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SampleWindow::kANGLE_DeviceType,
713cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
71474913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        SampleWindow::kRaster_DeviceType, // skip the null gpu device in normal cycling
715cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
716098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kRaster_DeviceType
7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
718cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gCT) == SampleWindow::kDeviceTypeCnt, array_size_mismatch);
7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gCT[ct];
7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
722f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.comstatic SkString getSampleTitle(const SkViewFactory* sampleFactory) {
723f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    SkView* view = (*sampleFactory)();
724f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    SkString title;
725f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    SampleCode::RequestTitle(view, &title);
726f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    view->unref();
727f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    return title;
728f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com}
729f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com
730de36b6948116a3d498ad8d808869ba182a66e206edisonn@google.comstatic bool compareSampleTitle(const SkViewFactory* first, const SkViewFactory* second) {
731f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    return strcmp(getSampleTitle(first).c_str(), getSampleTitle(second).c_str()) < 0;
7328570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com}
7338570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
734fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_string(slide, "", "Start on this sample.");
735fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_int32(msaa, 0, "Request multisampling with this count.");
736fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_string(pictureDir, "", "Read pictures from here.");
737fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_string(picture, "", "Path to single picture.");
738fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_bool(sort, false, "Sort samples by title.");
739fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_bool(list, false, "List samples?");
740fd117d8829407bb9903aafa436020d00ce762ec0mtklein#ifdef SAMPLE_PDF_FILE_VIEWER
741fd117d8829407bb9903aafa436020d00ce762ec0mtkleinDEFINE_string(pdfPath, "", "Path to direcotry of pdf files.");
742fd117d8829407bb9903aafa436020d00ce762ec0mtklein#endif
743fd117d8829407bb9903aafa436020d00ce762ec0mtklein
7444605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.comSampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager)
7454750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com    : INHERITED(hwnd)
7464750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com    , fDevManager(NULL) {
7478570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
748fd117d8829407bb9903aafa436020d00ce762ec0mtklein    SkCommandLineFlags::Parse(argc, argv);
749fd117d8829407bb9903aafa436020d00ce762ec0mtklein
7507d05ac9508bff5b1c62fec42dacb8aabd4cf8adbreed@google.com    fCurrIndex = -1;
7517d05ac9508bff5b1c62fec42dacb8aabd4cf8adbreed@google.com
752fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (!FLAGS_pictureDir.isEmpty()) {
753fd117d8829407bb9903aafa436020d00ce762ec0mtklein        SkOSFile::Iter iter(FLAGS_pictureDir[0], "skp");
754fd117d8829407bb9903aafa436020d00ce762ec0mtklein        SkString filename;
755fd117d8829407bb9903aafa436020d00ce762ec0mtklein        while (iter.next(&filename)) {
756fd117d8829407bb9903aafa436020d00ce762ec0mtklein            *fSamples.append() = new PictFileFactory(
757fd117d8829407bb9903aafa436020d00ce762ec0mtklein                    SkOSPath::SkPathJoin(FLAGS_pictureDir[0], filename.c_str()));
758fd117d8829407bb9903aafa436020d00ce762ec0mtklein        }
759fd117d8829407bb9903aafa436020d00ce762ec0mtklein    }
760fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (!FLAGS_picture.isEmpty()) {
761fd117d8829407bb9903aafa436020d00ce762ec0mtklein        SkString path(FLAGS_picture[0]);
762fd117d8829407bb9903aafa436020d00ce762ec0mtklein        fCurrIndex = fSamples.count();
763fd117d8829407bb9903aafa436020d00ce762ec0mtklein        *fSamples.append() = new PictFileFactory(path);
764fd117d8829407bb9903aafa436020d00ce762ec0mtklein    }
765f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com#ifdef SAMPLE_PDF_FILE_VIEWER
766fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (!FLAGS_pdfPath.isEmpty()) {
767fd117d8829407bb9903aafa436020d00ce762ec0mtklein        SkOSFile::Iter iter(FLAGS_pdfPath[0], "pdf");
768fd117d8829407bb9903aafa436020d00ce762ec0mtklein        SkString filename;
769fd117d8829407bb9903aafa436020d00ce762ec0mtklein        while (iter.next(&filename)) {
770fd117d8829407bb9903aafa436020d00ce762ec0mtklein            *fSamples.append() = new PdfFileViewerFactory(
771fd117d8829407bb9903aafa436020d00ce762ec0mtklein                    SkOSPath::SkPathJoin(FLAGS_pictureDir[0], filename.c_str()));
772fd117d8829407bb9903aafa436020d00ce762ec0mtklein        }
773fd117d8829407bb9903aafa436020d00ce762ec0mtklein    }
774fd117d8829407bb9903aafa436020d00ce762ec0mtklein#endif
77576d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    SkGMRegistyToSampleRegistry();
77676d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    {
77776d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        const SkViewRegister* reg = SkViewRegister::Head();
77876d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        while (reg) {
77976d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            *fSamples.append() = reg->factory();
78076d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            reg = reg->next();
78176d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        }
78276d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    }
78376d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com
784fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (FLAGS_sort) {
785f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com        // Sort samples, so foo.skp and foo.pdf are consecutive and we can quickly spot where
786f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com        // skp -> pdf -> png fails.
787f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com        SkTQSort(fSamples.begin(), fSamples.end() ? fSamples.end() - 1 : NULL, compareSampleTitle);
788f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    }
789f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com
790fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (!FLAGS_slide.isEmpty()) {
791fd117d8829407bb9903aafa436020d00ce762ec0mtklein        fCurrIndex = findByTitle(FLAGS_slide[0]);
792fd117d8829407bb9903aafa436020d00ce762ec0mtklein        if (fCurrIndex < 0) {
793fd117d8829407bb9903aafa436020d00ce762ec0mtklein            fprintf(stderr, "Unknown sample \"%s\"\n", FLAGS_slide[0]);
7947265e725555098637498db2f397623d7991ceb4brobertphillips@google.com            listTitles();
7958570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        }
7968570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
7978570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
798fd117d8829407bb9903aafa436020d00ce762ec0mtklein    fMSAASampleCount = FLAGS_msaa;
799fd117d8829407bb9903aafa436020d00ce762ec0mtklein
800fd117d8829407bb9903aafa436020d00ce762ec0mtklein    if (FLAGS_list) {
801fd117d8829407bb9903aafa436020d00ce762ec0mtklein        listTitles();
802fd117d8829407bb9903aafa436020d00ce762ec0mtklein    }
803fd117d8829407bb9903aafa436020d00ce762ec0mtklein
8048570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    if (fCurrIndex < 0) {
8058570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        SkString title;
8068570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        if (readTitleFromPrefs(&title)) {
8078570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            fCurrIndex = findByTitle(title.c_str());
8088570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        }
8098570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
8108570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
8118570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    if (fCurrIndex < 0) {
8128570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        fCurrIndex = 0;
8138570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
8148570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
8153cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com    gSampleWindow = this;
8163cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com
8171f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#ifdef  PIPE_FILE
8181f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    //Clear existing file or create file if it doesn't exist
8191f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    FILE* f = fopen(FILE_PATH, "wb");
8201f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    fclose(f);
8211f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#endif
8224605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
823bd8d7adb0ac9533a04e7b7a481371d4c66bbbc9brobertphillips@google.com    fDeviceType = kRaster_DeviceType;
824b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
825b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if DEFAULT_TO_GPU
826b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = kGPU_DeviceType;
827b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
828b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE && DEFAULT_TO_ANGLE
829b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = kANGLE_DeviceType;
83053e96a14cac520c1fd071ad65d80b5bacc5c4e28robertphillips@google.com#endif
831b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fUseClip = false;
833e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    fNClip = false;
8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fAnimating = false;
8356c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    fRotate = false;
836b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com    fRotateAnimTime = 0;
837e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    fPerspAnim = false;
838e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    fPerspAnimTime = 0;
839f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    fRequestGrabImage = false;
840b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fPipeState = SkOSMenu::kOffState;
841cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    fTilingMode = kNo_Tiling;
8422eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    fMeasureFPS = false;
843db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fLCDState = SkOSMenu::kMixedState;
844db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fAAState = SkOSMenu::kMixedState;
84596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    fSubpixelState = SkOSMenu::kMixedState;
84696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    fHintingState = 0;
84715bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    fFilterLevelIndex = 0;
848569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    fFlipAxis = 0;
8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fScrollTestX = fScrollTestY = 0;
8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8510f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseX = fMouseY = 0;
8523ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org    fFatBitsScale = 8;
8530f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
8540f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fShowZoomer = false;
8554605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
856dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    fZoomLevel = 0;
857dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    fZoomScale = SK_Scalar1;
8584605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
859db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fMagnify = false;
8604605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
8618ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fSaveToPdf = false;
8628ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fPdfCanvas = NULL;
8638ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
864db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fTransitionNext = 6;
865db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fTransitionPrev = 2;
8664605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
867921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    int sinkID = this->getSinkID();
8687dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu = new SkOSMenu;
8697dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->setTitle("Global Settings");
870db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    int itemID;
8714605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
8724605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Device Type", "Device Type", sinkID, 0,
8734605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Raster", "Picture", "OpenGL",
874b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
875b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                                "ANGLE",
876b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
877b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                                NULL);
8787dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'd');
8797dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("AA", "AA", sinkID, fAAState);
8807dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'b');
8817dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("LCD", "LCD", sinkID, fLCDState);
8827dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'l');
88315bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    itemID = fAppMenu->appendList("FilterLevel", "FilterLevel", sinkID, fFilterLevelIndex,
88415bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  gFilterLevelStates[0].fName,
88515bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  gFilterLevelStates[1].fName,
88615bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  gFilterLevelStates[2].fName,
88715bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  gFilterLevelStates[3].fName,
88815bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  gFilterLevelStates[4].fName,
88915bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                  NULL);
8907dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'n');
89196aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    itemID = fAppMenu->appendTriState("Subpixel", "Subpixel", sinkID, fSubpixelState);
89296aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 's');
89396aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    itemID = fAppMenu->appendList("Hinting", "Hinting", sinkID, fHintingState,
89496aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com                                  gHintingStates[0].name,
89596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com                                  gHintingStates[1].name,
89696aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com                                  gHintingStates[2].name,
89796aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com                                  gHintingStates[3].name,
898a9133bbcc6deceb5cd883305767093e10c17c359bungeman@google.com                                  gHintingStates[4].name,
899a9133bbcc6deceb5cd883305767093e10c17c359bungeman@google.com                                  NULL);
9007dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'h');
90167b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
902b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fUsePipeMenuItemID = fAppMenu->appendTriState("Pipe", "Pipe" , sinkID,
9034605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                                  fPipeState);
904b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fAppMenu->assignKeyEquivalentToItem(fUsePipeMenuItemID, 'P');
90567b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
906cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    itemID =fAppMenu->appendList("Tiling", "Tiling", sinkID, fTilingMode,
907cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kNo_Tiling].label,
908cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kAbs_128x128_Tiling].label,
909cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kAbs_256x256_Tiling].label,
910cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kRel_4x4_Tiling].label,
911cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kRel_1x16_Tiling].label,
912cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 gTilingInfo[kRel_16x1_Tiling].label,
913cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                                 NULL);
91467b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 't');
91567b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
9164605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Slide Show", "Slide Show" , sinkID, false);
9174605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'a');
9184605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Clip", "Clip" , sinkID, fUseClip);
9197dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'c');
9204605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Flip X", "Flip X" , sinkID, false);
9217dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'x');
9227dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Flip Y", "Flip Y" , sinkID, false);
9237dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'y');
9247dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Zoomer", "Zoomer" , sinkID, fShowZoomer);
9257dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'z');
9267dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Magnify", "Magnify" , sinkID, fMagnify);
9277dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'm');
9284605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Transition-Next", "Transition-Next", sinkID,
9294605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                fTransitionNext, "Up", "Up and Right", "Right",
9304605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Down and Right", "Down", "Down and Left",
931db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                "Left", "Up and Left", NULL);
9327dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'j');
9334605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Transition-Prev", "Transition-Prev", sinkID,
9344605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                fTransitionPrev, "Up", "Up and Right", "Right",
9354605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Down and Right", "Down", "Down and Left",
936db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                "Left", "Up and Left", NULL);
9377dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'k');
9387dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendAction("Save to PDF", sinkID);
9397dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'e');
9404605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
9417dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->addMenu(fAppMenu);
9427dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fSlideMenu = new SkOSMenu;
9437dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->addMenu(fSlideMenu);
9444605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
94528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    this->setColorType(kN32_SkColorType);
9462fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    this->setVisibleP(true);
947f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    this->setClipToBounds(false);
9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
94948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    this->loadView((*fSamples[fCurrIndex])());
9504605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
951840e9f3776ea99d9c1cfe5ccc0b85f3db3da9affbsalomon@google.com    fPDFData = NULL;
952f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
953098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (NULL == devManager) {
954098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        fDevManager = new DefaultDeviceManager();
955098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    } else {
956098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        devManager->ref();
957098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        fDevManager = devManager;
958098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
9591195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fDevManager->setUpBackend(this, fMSAASampleCount);
960098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
961b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // If another constructor set our dimensions, ensure that our
962b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // onSizeChange gets called.
963b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    if (this->height() && this->width()) {
964b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo        this->onSizeChange();
965b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    }
9662072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com
9672072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // can't call this synchronously, since it may require a subclass to
9682072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // to implement, or the caller may need us to have returned from the
9692072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // constructor first. Hence we post an event to ourselves.
9702072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com//    this->updateTitle();
9716de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org    post_event_to_sink(new SkEvent(gUpdateWindowTitleEvtName), this);
9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSampleWindow::~SampleWindow() {
9758ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    delete fPdfCanvas;
9760f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fTypeface->unref();
97729038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com
978098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    SkSafeUnref(fDevManager);
9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
981f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com
9826f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgint SampleWindow::findByTitle(const char title[]) {
9836f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    int i, count = fSamples.count();
9846f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    for (i = 0; i < count; i++) {
9856f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        if (getSampleTitle(i).equals(title)) {
9866f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            return i;
9876f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
9886f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
989dd52caaa093845c7c5157be78d94feb72f9cb155mike@reedtribe.org    return -1;
9906f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
9916f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
9927265e725555098637498db2f397623d7991ceb4brobertphillips@google.comvoid SampleWindow::listTitles() {
9937265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    int count = fSamples.count();
9947265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    SkDebugf("All Slides:\n");
9957265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    for (int i = 0; i < count; i++) {
9967265e725555098637498db2f397623d7991ceb4brobertphillips@google.com        SkDebugf("    %s\n", getSampleTitle(i).c_str());
9977265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    }
9987265e725555098637498db2f397623d7991ceb4brobertphillips@google.com}
9997265e725555098637498db2f397623d7991ceb4brobertphillips@google.com
100055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic SkBitmap capture_bitmap(SkCanvas* canvas) {
100155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkBitmap bm;
1002c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    if (bm.allocPixels(canvas->imageInfo())) {
1003c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        canvas->readPixels(&bm, 0, 0);
1004c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    }
100555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return bm;
100655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
100755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
100855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
100955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                        SkBitmap* diff) {
101055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
10112e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
101255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp0(src);
101355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp1(orig);
101455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    for (int y = 0; y < src.height(); y++) {
101555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* srcP = src.getAddr(0, y);
101655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* origP = orig.getAddr(0, y);
101755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        size_t bytes = src.width() * src.bytesPerPixel();
101855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (memcmp(srcP, origP, bytes)) {
101955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkDebugf("---------- difference on line %d\n", y);
102055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            return true;
102155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
102255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    }
102355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return false;
102455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
102555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
10260f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggostatic void drawText(SkCanvas* canvas, SkString string, SkScalar left, SkScalar top, SkPaint& paint)
10270f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
10280f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkColor desiredColor = paint.getColor();
10290f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.setColor(SK_ColorWHITE);
10300f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    const char* c_str = string.c_str();
10310f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    size_t size = string.size();
10320f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkRect bounds;
10330f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.measureText(c_str, size, &bounds);
10340f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    bounds.offset(left, top);
10350f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkScalar inset = SkIntToScalar(-2);
10360f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    bounds.inset(inset, inset);
10370f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    canvas->drawRect(bounds, paint);
10380f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (desiredColor != SK_ColorBLACK) {
10390f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
10400f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawText(c_str, size, left + SK_Scalar1, top + SK_Scalar1, paint);
10410f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
10420f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.setColor(desiredColor);
10430f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    canvas->drawText(c_str, size, left, top, paint);
10440f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
10450f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
10464417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define XCLIP_N  8
10474417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define YCLIP_N  8
1048e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
1049e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.comvoid SampleWindow::draw(SkCanvas* canvas) {
10504417740a480786ca65379ba5b398c500ba34ee18reed@android.com    // update the animation time
1051e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (!gAnimTimePrev && !gAnimTime) {
1052e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        // first time make delta be 0
1053e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTime = SkTime::GetMSecs();
1054e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTimePrev = gAnimTime;
1055e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    } else {
1056e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTimePrev = gAnimTime;
1057e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTime = SkTime::GetMSecs();
1058e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
10594605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1060f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fGesture.isActive()) {
1061f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
106252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
10634605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1064796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS) {
1065796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        fMeasureFPS_Time = 0;
1066796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    }
1067796763e0b2c06a7789185322561a1135e5484688djsollen@google.com
1068e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
106955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        this->INHERITED::draw(canvas);
107055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap orig = capture_bitmap(canvas);
1071e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
1072e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar w = this->width();
1073e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar h = this->height();
1074e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar cw = w / XCLIP_N;
1075e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar ch = h / YCLIP_N;
1076e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        for (int y = 0; y < YCLIP_N; y++) {
107755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkRect r;
107855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fTop = y * ch;
107955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fBottom = (y + 1) * ch;
108055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            if (y == YCLIP_N - 1) {
108155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fBottom = h;
108255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            }
1083e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            for (int x = 0; x < XCLIP_N; x++) {
1084e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                SkAutoCanvasRestore acr(canvas, true);
108555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fLeft = x * cw;
108655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fRight = (x + 1) * cw;
108755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                if (x == XCLIP_N - 1) {
108855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                    r.fRight = w;
108955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                }
1090e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                canvas->clipRect(r);
1091e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                this->INHERITED::draw(canvas);
1092e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            }
1093e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        }
10942e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
109555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap diff;
109655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (bitmap_diff(canvas, orig, &diff)) {
109755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
1098e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    } else {
1099bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        SkSize tile = this->tileSize();
1100cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
11019a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org        if (kNo_Tiling == fTilingMode) {
11029a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            this->INHERITED::draw(canvas); // no looping or surfaces needed
11039a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org        } else {
11049a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            const int w = SkScalarRoundToInt(tile.width());
11059a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            const int h = SkScalarRoundToInt(tile.height());
11069a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
11079a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
11089a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            SkCanvas* tileCanvas = surface->getCanvas();
11099a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org
11109a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            for (SkScalar y = 0; y < height(); y += tile.height()) {
11119a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                for (SkScalar x = 0; x < width(); x += tile.width()) {
11129a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    SkAutoCanvasRestore acr(tileCanvas, true);
11139a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    tileCanvas->translate(-x, -y);
11149a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    tileCanvas->clear(0);
11159a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    this->INHERITED::draw(tileCanvas);
11169a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    surface->draw(canvas, x, y, NULL);
11179a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                }
111885cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            }
1119ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
11209a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org            // for drawing the borders between tiles
112185cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            SkPaint paint;
112285cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            paint.setColor(0x60FF00FF);
112385cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            paint.setStyle(SkPaint::kStroke_Style);
1124cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org
1125cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org            for (SkScalar y = 0; y < height(); y += tile.height()) {
1126cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org                for (SkScalar x = 0; x < width(); x += tile.width()) {
11279a558d495dfe305a52946cdf97e8883190e0bbcccommit-bot@chromium.org                    canvas->drawRect(SkRect::MakeXYWH(x, y, tile.width(), tile.height()), paint);
112885cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                }
112985cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            }
113085cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        }
1131e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
1132098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (fShowZoomer && !fSaveToPdf) {
11333272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo        showZoomer(canvas);
11343272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo    }
1135db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (fMagnify && !fSaveToPdf) {
1136db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        magnify(canvas);
1137db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
11384605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1139796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS && fMeasureFPS_Time) {
1140796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        this->updateTitle();
1141796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        this->postInvalDelay();
1142796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    }
1143796763e0b2c06a7789185322561a1135e5484688djsollen@google.com
114429038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    // do this last
1145098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    fDevManager->publishCanvas(fDeviceType, canvas, this);
11463272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo}
11473272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo
1148db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic float clipW = 200;
1149db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic float clipH = 200;
1150db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleWindow::magnify(SkCanvas* canvas) {
1151db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkRect r;
1152db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    int count = canvas->save();
11534605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1154db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkMatrix m = canvas->getTotalMatrix();
115507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!m.invert(&m)) {
115607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
115707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
1158db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkPoint offset, center;
1159820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    SkScalar mouseX = fMouseX * SK_Scalar1;
1160820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    SkScalar mouseY = fMouseY * SK_Scalar1;
1161820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.mapXY(mouseX - clipW/2, mouseY - clipH/2, &offset);
1162820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.mapXY(mouseX, mouseY, &center);
11634605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1164db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    r.set(0, 0, clipW * m.getScaleX(), clipH * m.getScaleX());
1165db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    r.offset(offset.fX, offset.fY);
11664605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1167db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkPaint paint;
1168db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    paint.setColor(0xFF66AAEE);
1169db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    paint.setStyle(SkPaint::kStroke_Style);
1170820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    paint.setStrokeWidth(10.f * m.getScaleX());
1171db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    //lense offset
1172db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    //canvas->translate(0, -250);
1173db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->drawRect(r, paint);
1174db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->clipRect(r);
11754605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1176db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m = canvas->getTotalMatrix();
1177db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m.setTranslate(-center.fX, -center.fY);
1178820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.postScale(0.5f * fFatBitsScale, 0.5f * fFatBitsScale);
1179db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m.postTranslate(center.fX, center.fY);
1180db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->concat(m);
11814605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1182db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    this->INHERITED::draw(canvas);
11834605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1184db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->restoreToCount(count);
1185db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
1186db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
11873272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggovoid SampleWindow::showZoomer(SkCanvas* canvas) {
11880f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        int count = canvas->save();
11890f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->resetMatrix();
11900f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Ensure the mouse position is on screen.
1191e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com        int width = SkScalarRoundToInt(this->width());
1192e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com        int height = SkScalarRoundToInt(this->height());
11930f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (fMouseX >= width) fMouseX = width - 1;
11940f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        else if (fMouseX < 0) fMouseX = 0;
11950f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (fMouseY >= height) fMouseY = height - 1;
11960f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        else if (fMouseY < 0) fMouseY = 0;
1197b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com
11980f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkBitmap bitmap = capture_bitmap(canvas);
1199b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com        bitmap.lockPixels();
1200b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com
12010f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Find the size of the zoomed in view, forced to be odd, so the examined pixel is in the middle.
12023ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org        int zoomedWidth = (width >> 1) | 1;
12033ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org        int zoomedHeight = (height >> 1) | 1;
12040f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkIRect src;
12050f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        src.set(0, 0, zoomedWidth / fFatBitsScale, zoomedHeight / fFatBitsScale);
12060f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        src.offset(fMouseX - (src.width()>>1), fMouseY - (src.height()>>1));
12070f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect dest;
12080f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        dest.set(0, 0, SkIntToScalar(zoomedWidth), SkIntToScalar(zoomedHeight));
12090f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        dest.offset(SkIntToScalar(width - zoomedWidth), SkIntToScalar(height - zoomedHeight));
12100f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkPaint paint;
12110f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Clear the background behind our zoomed in view
12120f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorWHITE);
12130f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawRect(dest, paint);
12140f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawBitmapRect(bitmap, &src, dest);
12150f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
12160f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setStyle(SkPaint::kStroke_Style);
12170f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Draw a border around the pixel in the middle
12180f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect originalPixel;
12190f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        originalPixel.set(SkIntToScalar(fMouseX), SkIntToScalar(fMouseY), SkIntToScalar(fMouseX + 1), SkIntToScalar(fMouseY + 1));
12200f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkMatrix matrix;
12210f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect scalarSrc;
12220f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        scalarSrc.set(src);
12230f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkColor color = bitmap.getColor(fMouseX, fMouseY);
12240f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (matrix.setRectToRect(scalarSrc, dest, SkMatrix::kFill_ScaleToFit)) {
12250f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            SkRect pixel;
12260f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            matrix.mapRect(&pixel, originalPixel);
12270f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            // TODO Perhaps measure the values and make the outline white if it's "dark"
12280f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            if (color == SK_ColorBLACK) {
12290f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo                paint.setColor(SK_ColorWHITE);
12300f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            }
12310f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            canvas->drawRect(pixel, paint);
12320f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        }
12330f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
12340f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Draw a border around the destination rectangle
12350f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawRect(dest, paint);
12360f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setStyle(SkPaint::kStrokeAndFill_Style);
12370f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Identify the pixel and its color on screen
12380f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setTypeface(fTypeface);
12390f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setAntiAlias(true);
12400f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar lineHeight = paint.getFontMetrics(NULL);
12410f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkString string;
12420f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("(%i, %i)", fMouseX, fMouseY);
12430f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar left = dest.fLeft + SkIntToScalar(3);
12440f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar i = SK_Scalar1;
12450f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12460f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Alpha
12470f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12480f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12490f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("A: %X", SkColorGetA(color));
12500f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12510f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Red
12520f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12530f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12540f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("R: %X", SkColorGetR(color));
12550f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorRED);
12560f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12570f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Green
12580f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12590f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12600f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("G: %X", SkColorGetG(color));
12610f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorGREEN);
12620f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12630f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Blue
12640f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12650f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12660f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("B: %X", SkColorGetB(color));
12670f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLUE);
12680f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12690f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->restoreToCount(count);
1270e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com}
1271e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onDraw(SkCanvas* canvas) {
12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
12748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12778ac0d542b0226e68b0faa935b3402ffc91409a02Scroggovoid SampleWindow::saveToPdf()
12788ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo{
12798ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fSaveToPdf = true;
12808ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    this->inval(NULL);
12818ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo}
12828ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
12848ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    if (fSaveToPdf) {
12858ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false);
12868ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkISize size = SkISize::Make(bmp.width(), bmp.height());
12878ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDevice* pdfDevice = new SkPDFDevice(size, size,
12888ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo                canvas->getTotalMatrix());
12898ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fPdfCanvas = new SkCanvas(pdfDevice);
12908ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        pdfDevice->unref();
12918ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        canvas = fPdfCanvas;
129282502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com    } else if (kPicture_DeviceType == fDeviceType) {
12935fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org        canvas = fRecorder.beginRecording(9999, 9999, NULL, 0);
12948ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    } else {
1295cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
129682502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        if (kNullGPU_DeviceType != fDeviceType)
1297cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
129882502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        {
129982502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            canvas = this->INHERITED::beforeChildren(canvas);
1300ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fUseClip) {
13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawColor(0xFFFF88FF);
1305045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com        canvas->clipPath(fClipPath, SkRegion::kIntersect_Op, true);
13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return canvas;
13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void paint_rgn(const SkBitmap& bm, const SkIRect& r,
13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                      const SkRegion& rgn) {
13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkCanvas    canvas(bm);
13148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRegion    inval(rgn);
13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inval.translate(r.fLeft, r.fTop);
13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.clipRegion(inval);
13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.drawColor(0xFFFF8080);
13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1320501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#include "SkData.h"
13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::afterChildren(SkCanvas* orig) {
13228ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    if (fSaveToPdf) {
13238ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fSaveToPdf = false;
13248ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        if (fShowZoomer) {
13258ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            showZoomer(fPdfCanvas);
13268ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        }
13278ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkString name;
13288ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        name.printf("%s.pdf", this->getTitle());
13298ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDocument doc;
13308ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
13318ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        doc.appendPage(device);
133256c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
13338ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        name.prepend("/sdcard/");
13348ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo#endif
13354605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1336501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#ifdef SK_BUILD_FOR_IOS
1337501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com        SkDynamicMemoryWStream mstream;
1338501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com        doc.emitPDF(&mstream);
1339ae8a2e5cba553267b189b8b5cae40330c4ff5bdbyangsu@google.com        fPDFData = mstream.copyToData();
1340501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#endif
13418ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkFILEWStream stream(name.c_str());
13428ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        if (stream.isValid()) {
13438ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            doc.emitPDF(&stream);
13448ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            const char* desc = "File saved from Skia SampleApp";
13458ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            this->onPDFSaved(this->getTitle(), desc, name.c_str());
13468ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        }
13474605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
13488ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        delete fPdfCanvas;
13498ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fPdfCanvas = NULL;
13508ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
13518ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        // We took over the draw calls in order to create the PDF, so we need
13528ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        // to redraw.
13538ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        this->inval(NULL);
13548ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        return;
13558ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    }
13564605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1357f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (fRequestGrabImage) {
1358f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        fRequestGrabImage = false;
13592e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
13601f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        SkBaseDevice* device = orig->getDevice();
1361669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com        SkBitmap bmp;
136228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        if (device->accessBitmap(false).copyTo(&bmp, kN32_SkColorType)) {
1363f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            static int gSampleGrabCounter;
1364f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkString name;
13657c57e0e7ccb05a4b7ce05b883ba06380d5578881reed@google.com            name.printf("sample_grab_%d.png", gSampleGrabCounter++);
1366669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com            SkImageEncoder::EncodeFile(name.c_str(), bmp,
1367f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                                       SkImageEncoder::kPNG_Type, 100);
1368f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1369f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1370f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1371098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (kPicture_DeviceType == fDeviceType) {
137284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkAutoTUnref<SkPicture> picture(fRecorder.endRecording());
137384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com
1374098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        if (true) {
137584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkPicture* pict = new SkPicture(*picture);
1376e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com            this->installDrawFilter(orig);
13779b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips            orig->drawPicture(pict);
1378098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            pict->unref();
1379098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        } else if (true) {
1380098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkDynamicMemoryWStream ostream;
138184b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            picture->serialize(&ostream);
1382098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
1383098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkAutoDataUnref data(ostream.copyToData());
138459f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com            SkMemoryStream istream(data->data(), data->size());
1385f1754ec69131801c1a6ed3c704501a9400bbf324scroggo@google.com            SkAutoTUnref<SkPicture> pict(SkPicture::CreateFromStream(&istream));
1386f1754ec69131801c1a6ed3c704501a9400bbf324scroggo@google.com            if (pict.get() != NULL) {
13879b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips                orig->drawPicture(pict.get());
1388f1754ec69131801c1a6ed3c704501a9400bbf324scroggo@google.com            }
1389098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        } else {
139084b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            picture->draw(orig);
1391098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
13928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
13932e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
139417d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    // Do this after presentGL and other finishing, rather than in afterChild
1395796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS && fMeasureFPS_StartTime) {
1396796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        fMeasureFPS_Time += SkTime::GetMSecs() - fMeasureFPS_StartTime;
139717d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    }
139817d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com
139917d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    //    if ((fScrollTestX | fScrollTestY) != 0)
1400f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (false) {
14018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
14028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dx = fScrollTestX * 7;
14038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dy = fScrollTestY * 7;
14048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIRect r;
14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRegion inval;
14062e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(50, 50, 50+100, 50+100);
14088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bm.scrollRect(&r, dx, dy, &inval);
14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint_rgn(bm, r, inval);
1410ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    }
14118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14136c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
14146c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
1415b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com        fRotateAnimTime += SampleCode::GetAnimSecondsDelta();
1416b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com
14176c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cx = this->width() / 2;
14186c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cy = this->height() / 2;
14196c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(cx, cy);
1420b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com        canvas->rotate(fRotateAnimTime * 10);
14216c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(-cx, -cy);
14226c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
1423b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com
1424e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (fPerspAnim) {
14256fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        fPerspAnimTime += SampleCode::GetAnimSecondsDelta();
14266fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com
14276fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        static const SkScalar gAnimPeriod = 10 * SK_Scalar1;
14286fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        static const SkScalar gAnimMag = SK_Scalar1 / 1000;
14296fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        SkScalar t = SkScalarMod(fPerspAnimTime, gAnimPeriod);
14306fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        if (SkScalarFloorToInt(SkScalarDiv(fPerspAnimTime, gAnimPeriod)) & 0x1) {
14316fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            t = gAnimPeriod - t;
14326fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        }
14336fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        t = 2 * t - gAnimPeriod;
14346fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        t = SkScalarMul(SkScalarDiv(t, gAnimPeriod), gAnimMag);
14356fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        SkMatrix m;
14366fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        m.reset();
14376fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        m.setPerspY(t);
1438e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        canvas->concat(m);
1439e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
1440f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
1441e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com    this->installDrawFilter(canvas);
14422eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
14432eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (fMeasureFPS) {
1444f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        if (SampleView::SetRepeatDraw(child, FPS_REPEAT_COUNT)) {
1445796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            fMeasureFPS_StartTime = SkTime::GetMSecs();
1446f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        }
1447f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    } else {
1448f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        (void)SampleView::SetRepeatDraw(child, 1);
14492eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
1450b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com    if (fPerspAnim || fRotate) {
1451e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        this->inval(NULL);
1452e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
14536c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
14546c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
14556c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
1456f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    canvas->setDrawFilter(NULL);
14576c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
14586c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
1459e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.orgstatic SkColorType gColorTypeCycle[] = {
1460e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    kUnknown_SkColorType,           // none -> none
1461e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    kUnknown_SkColorType,           // a8 -> none
1462fb6fefed0976d7fed193155900a186dc880451b6commit-bot@chromium.org    kN32_SkColorType,               // 565 -> 8888
146328fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    kN32_SkColorType,               // 4444 -> 8888
1464e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    kRGB_565_SkColorType,           // 8888 -> 565
1465e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    kRGB_565_SkColorType,           // 8888 -> 565
1466e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    kUnknown_SkColorType,           // index8 -> none
14678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
14688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1469a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.orgstatic SkColorType cycle_colortypes(SkColorType c) {
1470e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org    return gColorTypeCycle[c];
14718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1473e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.comvoid SampleWindow::changeZoomLevel(float delta) {
14744b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    fZoomLevel += delta;
1475dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (fZoomLevel > 0) {
1476e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
1477e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomScale = fZoomLevel + SK_Scalar1;
1478dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    } else if (fZoomLevel < 0) {
1479e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
1480e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
1481dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    } else {
1482dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        fZoomScale = SK_Scalar1;
1483dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
1484f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->updateMatrix();
1485f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
1486dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
1487f03bb566e25ace918f8fdda3cb8426626a00894creed@google.comvoid SampleWindow::updateMatrix(){
1488f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    SkMatrix m;
1489f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.reset();
1490f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fZoomLevel) {
1491f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkPoint center;
1492f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        //m = this->getLocalMatrix();//.invert(&m);
1493f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.mapXY(fZoomCenterX, fZoomCenterY, &center);
1494f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkScalar cx = center.fX;
1495f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkScalar cy = center.fY;
14964605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1497f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.setTranslate(-cx, -cy);
1498f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.postScale(fZoomScale, fZoomScale);
1499f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.postTranslate(cx, cy);
1500f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
15014605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1502f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fFlipAxis) {
1503f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.preTranslate(fZoomCenterX, fZoomCenterY);
1504f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        if (fFlipAxis & kFlipAxis_X) {
1505f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            m.preScale(-SK_Scalar1, SK_Scalar1);
1506f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
1507f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        if (fFlipAxis & kFlipAxis_Y) {
1508f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            m.preScale(SK_Scalar1, -SK_Scalar1);
1509f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
1510f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.preTranslate(-fZoomCenterX, -fZoomCenterY);
1511f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        //canvas->concat(m);
1512f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
1513f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    // Apply any gesture matrix
1514f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.preConcat(fGesture.localM());
1515f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.preConcat(fGesture.globalM());
15164605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1517f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->setLocalMatrix(m);
15184605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1519e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com    this->updateTitle();
1520dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    this->inval(NULL);
1521dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org}
15222c8208f3a444098aee562f5a1ef620142807eda2Scroggobool SampleWindow::previousSample() {
152362b65b0913566381db468277de07e5dd2a9237caScroggo    fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count();
15244605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
1525db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     fTransitionPrev));
15262c8208f3a444098aee562f5a1ef620142807eda2Scroggo    return true;
15272c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
15282c8208f3a444098aee562f5a1ef620142807eda2Scroggo
15298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::nextSample() {
153034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    fCurrIndex = (fCurrIndex + 1) % fSamples.count();
15314605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
1532db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     fTransitionNext));
153334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    return true;
15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
15358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1536501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.combool SampleWindow::goToSample(int i) {
1537501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    fCurrIndex = (i) % fSamples.count();
153848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    this->loadView(create_transition(curr_view(this),(*fSamples[fCurrIndex])(), 6));
1539501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    return true;
1540501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1541501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1542501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.comSkString SampleWindow::getSampleTitle(int i) {
1543f8b6b01d51d08e39499d1c88063af2964fe72a0fedisonn@google.com    return ::getSampleTitle(fSamples[i]);
1544501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1545501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1546501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.comint SampleWindow::sampleCount() {
1547501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    return fSamples.count();
1548501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1549501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1550db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleWindow::showOverview() {
15514605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this),
15524605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                     create_overview(fSamples.count(), fSamples.begin()),
1553db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     4));
1554db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
1555db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
1556e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.comvoid SampleWindow::installDrawFilter(SkCanvas* canvas) {
155715bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    canvas->setDrawFilter(new FlagsDrawFilter(fLCDState, fAAState, fSubpixelState,
155815bc13d20fe79914c7128881e45064becd11bc9dreed@google.com                                              fHintingState, fFilterLevelIndex))->unref();
1559e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com}
1560e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com
15612c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::postAnimatingEvent() {
15622c8208f3a444098aee562f5a1ef620142807eda2Scroggo    if (fAnimating) {
156387fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com        (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATING_DELAY);
15642c8208f3a444098aee562f5a1ef620142807eda2Scroggo    }
15652c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
1566e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com
15678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onEvent(const SkEvent& evt) {
15682072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    if (evt.isType(gUpdateWindowTitleEvtName)) {
15692072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com        this->updateTitle();
15702072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com        return true;
15712072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    }
15728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (evt.isType(ANIMATING_EVENTTYPE)) {
15738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fAnimating) {
15748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->nextSample();
15758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->postAnimatingEvent();
15768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
15778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
15788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1579ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (evt.isType("replace-transition-view")) {
1580ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->loadView((SkView*)SkEventSink::FindSink(evt.getFast32()));
1581db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
1582db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
158334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    if (evt.isType("set-curr-index")) {
1584db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->goToSample(evt.getFast32());
158534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        return true;
158634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    }
15872eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (isInvalEvent(evt)) {
15882eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        this->inval(NULL);
15892eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        return true;
15902eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
1591921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    int selected = -1;
1592ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) {
1593921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->setDeviceType((DeviceType)selected);
15944605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        return true;
1595921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1596b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (SkOSMenu::FindTriState(evt, "Pipe", &fPipeState)) {
1597ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com#ifdef PIPE_NET
1598b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (!fPipeState != SkOSMenu::kOnState)
1599ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            gServer.disconnectAll();
1600ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com#endif
1601b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        (void)SampleView::SetUsePipe(curr_view(this), fPipeState);
1602ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->updateTitle();
1603ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->inval(NULL);
1604921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1605921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1606ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Slide Show", NULL)) {
1607921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->toggleSlideshow();
1608921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1609921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1610ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindTriState(evt, "AA", &fAAState) ||
1611ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindTriState(evt, "LCD", &fLCDState) ||
161215bc13d20fe79914c7128881e45064becd11bc9dreed@google.com        SkOSMenu::FindListIndex(evt, "FilterLevel", &fFilterLevelIndex) ||
161396aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com        SkOSMenu::FindTriState(evt, "Subpixel", &fSubpixelState) ||
161496aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com        SkOSMenu::FindListIndex(evt, "Hinting", &fHintingState) ||
1615ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Clip", &fUseClip) ||
1616ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Zoomer", &fShowZoomer) ||
1617ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Magnify", &fMagnify) ||
1618ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindListIndex(evt, "Transition-Next", &fTransitionNext) ||
1619bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        SkOSMenu::FindListIndex(evt, "Transition-Prev", &fTransitionPrev)) {
1620bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        this->inval(NULL);
1621bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        this->updateTitle();
1622bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        return true;
1623bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    }
1624bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    if (SkOSMenu::FindListIndex(evt, "Tiling", &fTilingMode)) {
1625bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        if (SampleView::IsSampleView(curr_view(this))) {
1626bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org            ((SampleView*)curr_view(this))->onTileSizeChanged(this->tileSize());
1627bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        }
1628921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->inval(NULL);
1629921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->updateTitle();
1630921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1631921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1632ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) {
1633921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        fFlipAxis ^= kFlipAxis_X;
1634f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
1635921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1636921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1637ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) {
1638921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        fFlipAxis ^= kFlipAxis_Y;
1639f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
1640921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1641921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1642ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindAction(evt,"Save to PDF")) {
1643921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->saveToPdf();
1644921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
16454605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
16468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onEvent(evt);
16478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1649f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleWindow::onQuery(SkEvent* query) {
1650f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-count")) {
1651f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        query->setFast32(fSamples.count());
1652f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
1653f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1654f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-title")) {
165548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        SkView* view = (*fSamples[query->getFast32()])();
1656f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gTitleEvtName);
1657f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->doQuery(&evt)) {
1658f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            query->setString("title", evt.findString(gTitleEvtName));
1659f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1660f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkSafeUnref(view);
1661f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
1662f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1663f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("use-fast-text")) {
1664f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gFastTextEvtName);
1665f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return curr_view(this)->doQuery(&evt);
1666f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
166729038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    if (query->isType("ignore-window-bitmap")) {
166829038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        query->setFast32(this->getGrContext() != NULL);
166929038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        return true;
167029038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    }
1671f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return this->INHERITED::onQuery(query);
1672f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
1673f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
167402939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#if 0 // UNUSED
16750ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.comstatic void cleanup_for_filename(SkString* name) {
16760ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    char* str = name->writable_str();
1677e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com    for (size_t i = 0; i < name->size(); i++) {
16780ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        switch (str[i]) {
16790ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ':': str[i] = '-'; break;
16800ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case '/': str[i] = '-'; break;
16810ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ' ': str[i] = '_'; break;
16820ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            default: break;
16830ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        }
16840ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    }
16850ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com}
168602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#endif
16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleChar(SkUnichar uni) {
1689f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
1690f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
1691f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
1692f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gCharEvtName);
1693f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(uni);
1694f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
1695f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
1696f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
1697f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1698f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
16994605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
17008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dx = 0xFF;
17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dy = 0xFF;
17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (uni) {
17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '5': dx =  0; dy =  0; break;
17058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '8': dx =  0; dy = -1; break;
17068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '6': dx =  1; dy =  0; break;
17078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '2': dx =  0; dy =  1; break;
17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '4': dx = -1; dy =  0; break;
17098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '7': dx = -1; dy = -1; break;
17108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '9': dx =  1; dy = -1; break;
17118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '3': dx =  1; dy =  1; break;
17128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '1': dx = -1; dy =  1; break;
17132e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
17148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17172e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
17188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0xFF != dx && 0xFF != dy) {
17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((dx | dy) == 0) {
17208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX = fScrollTestY = 0;
17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX += dx;
17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestY += dy;
17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
17278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17282e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
17290ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    switch (uni) {
1730a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com        case 'B':
17316de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org            post_event_to_sink(SkNEW_ARGS(SkEvent, ("PictFileView::toggleBBox")), curr_view(this));
17326de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org            // Cannot call updateTitle() synchronously, because the toggleBBox event is still in
17336de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org            // the queue.
17346de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org            post_event_to_sink(SkNEW_ARGS(SkEvent, (gUpdateWindowTitleEvtName)), this);
1735a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            this->inval(NULL);
1736a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            break;
1737ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        case 'f':
17384605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com            // only
17396ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com            toggleFPS();
1740ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            break;
1741f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        case 'g':
1742f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            fRequestGrabImage = true;
1743f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            this->inval(NULL);
1744a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            break;
1745a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com        case 'G':
1746a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            gShowGMBounds = !gShowGMBounds;
17476de4a7836f1c7988b42cbbfe1a339ef7619aed8fcommit-bot@chromium.org            post_event_to_sink(GMSampleView::NewShowSizeEvt(gShowGMBounds),
1748a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com                            curr_view(this));
1749a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            this->inval(NULL);
1750f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
17512eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        case 'i':
17522eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->zoomIn();
17532eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            break;
175408526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo        case 'o':
175508526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo            this->zoomOut();
175608526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo            break;
17572eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        case 'r':
17582eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            fRotate = !fRotate;
1759b17859133aeb0ebe80805fbd437759e2b956d859bungeman@google.com            fRotateAnimTime = 0;
17602eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->inval(NULL);
17612eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->updateTitle();
17622eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            return true;
1763e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        case 'k':
1764e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            fPerspAnim = !fPerspAnim;
1765e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            this->inval(NULL);
1766e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            this->updateTitle();
1767e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            return true;
1768cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
176974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        case '\\':
1770b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->setDeviceType(kNullGPU_DeviceType);
1771b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->inval(NULL);
1772b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->updateTitle();
177374913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com            return true;
177405e70247c31ae927074ef27ea9893634a8dda543twiz@google.com        case 'p':
177505e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            {
177605e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                GrContext* grContext = this->getGrContext();
177705e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                if (grContext) {
177895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org                    size_t cacheBytes;
177995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org                    grContext->getResourceCacheUsage(NULL, &cacheBytes);
178005e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                    grContext->freeGpuResources();
178195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org                    SkDebugf("Purged %d bytes from the GPU resource cache.\n", cacheBytes);
178205e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                }
178305e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            }
178405e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            return true;
1785cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
17860ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        default:
17870ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            break;
17888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17894605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
17907dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    if (fAppMenu->handleKeyEquivalent(uni)|| fSlideMenu->handleKeyEquivalent(uni)) {
17917dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com        this->onUpdateMenu(fAppMenu);
17927dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com        this->onUpdateMenu(fSlideMenu);
1793db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
1794db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleChar(uni);
17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1798921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.comvoid SampleWindow::setDeviceType(DeviceType type) {
1799b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    if (type == fDeviceType)
1800b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        return;
1801b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1802b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDevManager->tearDownBackend(this);
1803b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1804b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = type;
1805b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
18061195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fDevManager->setUpBackend(this, fMSAASampleCount);
1807b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1808921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    this->updateTitle();
1809921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    this->inval(NULL);
1810921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com}
1811921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com
18122c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::toggleSlideshow() {
18132c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fAnimating = !fAnimating;
18142c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->postAnimatingEvent();
18152c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->updateTitle();
18162c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
18172c8208f3a444098aee562f5a1ef620142807eda2Scroggo
18182c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::toggleRendering() {
1819b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    this->setDeviceType(cycle_devicetype(fDeviceType));
18202c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->updateTitle();
18212c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->inval(NULL);
18222c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
18232c8208f3a444098aee562f5a1ef620142807eda2Scroggo
18246ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.comvoid SampleWindow::toggleFPS() {
18256ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    fMeasureFPS = !fMeasureFPS;
18266ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    this->updateTitle();
18276ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    this->inval(NULL);
18286ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com}
18296ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com
18308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDumpCanvas.h"
18318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleKey(SkKey key) {
1833f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
1834f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
1835f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
1836f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gKeyEvtName);
1837f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(key);
1838f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
1839f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
1840f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
1841f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1842f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (key) {
18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kRight_SkKey:
18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (this->nextSample()) {
18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
18498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kLeft_SkKey:
1850e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com            if (this->previousSample()) {
1851e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com                return true;
1852e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com            }
18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kUp_SkKey:
1855dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if (USE_ARROWS_FOR_ZOOM) {
1856cefd981a4c4e90be33d1433592f11f84a102d2e0bungeman@google.com                this->changeZoomLevel(1.f / 32.f);
1857dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            } else {
1858dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                fNClip = !fNClip;
1859dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                this->inval(NULL);
1860e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->updateTitle();
1861dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
18628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kDown_SkKey:
1864dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if (USE_ARROWS_FOR_ZOOM) {
1865cefd981a4c4e90be33d1433592f11f84a102d2e0bungeman@google.com                this->changeZoomLevel(-1.f / 32.f);
1866dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            } else {
1867a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org                this->setColorType(cycle_colortypes(this->getBitmap().colorType()));
1868e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->updateTitle();
1869dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
18708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18716f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        case kOK_SkKey: {
18726f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            SkString title;
18736f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            if (curr_title(this, &title)) {
18746f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org                writeTitleToPrefs(title.c_str());
18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18776f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
187834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        case kBack_SkKey:
1879db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            this->showOverview();
188034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            return true;
18818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
18828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
18838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleKey(key);
18858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
18868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com///////////////////////////////////////////////////////////////////////////////
188852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
188952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.comstatic const char gGestureClickType[] = "GestureClickType";
189052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
1891d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggobool SampleWindow::onDispatchClick(int x, int y, Click::State state,
18924d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        void* owner, unsigned modi) {
18930f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (Click::kMoved_State == state) {
18940f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        updatePointer(x, y);
18950f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
1896e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com    int w = SkScalarRoundToInt(this->width());
1897e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com    int h = SkScalarRoundToInt(this->height());
1898dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
1899dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    // check for the resize-box
1900dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (w - x < 16 && h - y < 16) {
1901dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return false;   // let the OS handle the click
19024605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
1903db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    else if (fMagnify) {
1904db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        //it's only necessary to update the drawing if there's a click
1905db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->inval(NULL);
1906db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return false; //prevent dragging while magnify is enabled
19074d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    } else {
19084d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        // capture control+option, and trigger debugger
19094d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        if ((modi & kControl_SkModifierKey) && (modi & kOption_SkModifierKey)) {
19104d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            if (Click::kDown_State == state) {
19114d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                SkEvent evt("debug-hit-test");
19124d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                evt.setS32("debug-hit-test-x", x);
19134d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                evt.setS32("debug-hit-test-y", y);
19144d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                curr_view(this)->doEvent(evt);
19154d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            }
19164d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            return true;
19174d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        } else {
19184d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            return this->INHERITED::onDispatchClick(x, y, state, owner, modi);
19194d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        }
1920dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
1921dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org}
1922dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
192352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.comclass GestureClick : public SkView::Click {
192452f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.compublic:
192552f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    GestureClick(SkView* target) : SkView::Click(target) {
192652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        this->setType(gGestureClickType);
192752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
192852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
192952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    static bool IsGesture(Click* click) {
193052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        return click->isType(gGestureClickType);
193152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
193252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com};
193352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
19344d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SampleWindow::onFindClickHandler(SkScalar x, SkScalar y,
19354d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                                                unsigned modi) {
193652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    return new GestureClick(this);
193752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com}
193852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
193952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.combool SampleWindow::onClick(Click* click) {
194052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    if (GestureClick::IsGesture(click)) {
19414d4f281b28c3db0513ea1a68db4577e2518002b3bsalomon@google.com        float x = static_cast<float>(click->fICurr.fX);
19424d4f281b28c3db0513ea1a68db4577e2518002b3bsalomon@google.com        float y = static_cast<float>(click->fICurr.fY);
19434605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
194452f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        switch (click->fState) {
194552f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kDown_State:
1946d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchBegin(click->fOwner, x, y);
194752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
194852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kMoved_State:
1949d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchMoved(click->fOwner, x, y);
1950f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com                this->updateMatrix();
195152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
195252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kUp_State:
1953d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchEnd(click->fOwner);
1954f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com                this->updateMatrix();
195552f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
195652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        }
195752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        return true;
195852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
195952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    return false;
196052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com}
196152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
196252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com///////////////////////////////////////////////////////////////////////////////
196352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
19648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::loadView(SkView* view) {
19658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
19668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* prev = iter.next();
19678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (prev) {
19688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        prev->detachFromParent();
19698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
19704605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
19718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setVisibleP(true);
1972f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    view->setClipToBounds(false);
19738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->attachChildToFront(view)->unref();
19748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
19758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1976921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    //repopulate the slide menu when a view is loaded
19777dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fSlideMenu->reset();
1978388974f1dd4d7f1a202aac8a007dc2a4eaf051cbdjsollen@google.com
1979b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    (void)SampleView::SetUsePipe(view, fPipeState);
1980bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    if (SampleView::IsSampleView(view)) {
1981bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        SampleView* sampleView = (SampleView*)view;
1982bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        sampleView->requestMenu(fSlideMenu);
1983bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        sampleView->onTileSizeChanged(this->tileSize());
1984bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    }
19857dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->onUpdateMenu(fSlideMenu);
19868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();
19878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
19888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1989098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comstatic const char* gDeviceTypePrefix[] = {
19908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "raster: ",
19918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "picture: ",
1992cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
199374913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com    "opengl: ",
1994b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
1995b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    "angle: ",
1996cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
199774913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com    "null-gl: "
1998cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
19998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2000cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comSK_COMPILE_ASSERT(SK_ARRAY_COUNT(gDeviceTypePrefix) == SampleWindow::kDeviceTypeCnt,
2001cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com                  array_size_mismatch);
20028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2003db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic const char* trystate_str(SkOSMenu::TriState state,
2004569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com                                const char trueStr[], const char falseStr[]) {
2005db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (SkOSMenu::kOnState == state) {
2006569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        return trueStr;
2007db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    } else if (SkOSMenu::kOffState == state) {
2008569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        return falseStr;
2009569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    }
2010569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    return NULL;
2011569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com}
2012569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
20138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::updateTitle() {
20146f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkView* view = curr_view(this);
20158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20166f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString title;
20176f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!curr_title(this, &title)) {
20188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.set("<unknown>");
20198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
20202e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2021098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    title.prepend(gDeviceTypePrefix[fDeviceType]);
20228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(" ");
2024c3b3266b7db2f1a41d41ecac010c766b7ad8eebcreed    title.prepend(sk_tool_utils::colortype_name(this->getBitmap().colorType()));
20252e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2026cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    if (fTilingMode != kNo_Tiling) {
2027cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org        title.prependf("<T: %s> ", gTilingInfo[fTilingMode].label);
2028cc63b32eb8702bfa4d965fa443cf00fc1c1d10b7commit-bot@chromium.org    }
20298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fAnimating) {
20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.prepend("<A> ");
20318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
20326c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
20336c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        title.prepend("<R> ");
20346c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
2035e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
2036e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        title.prepend("<C> ");
2037e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
2038e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (fPerspAnim) {
2039e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        title.prepend("<K> ");
2040e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
2041569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
2042569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(trystate_str(fLCDState, "LCD ", "lcd "));
2043569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(trystate_str(fAAState, "AA ", "aa "));
204415bc13d20fe79914c7128881e45064becd11bc9dreed@google.com    title.prepend(gFilterLevelStates[fFilterLevelIndex].fLabel);
204596aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    title.prepend(trystate_str(fSubpixelState, "S ", "s "));
2046569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(fFlipAxis & kFlipAxis_X ? "X " : NULL);
2047569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(fFlipAxis & kFlipAxis_Y ? "Y " : NULL);
204896aabc850835f6d08a117c0277be93848ddbf785bungeman@google.com    title.prepend(gHintingStates[fHintingState].label);
2049dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
2050dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (fZoomLevel) {
2051e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        title.prependf("{%.2f} ", SkScalarToFloat(fZoomLevel));
2052dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
20534605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
20542eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (fMeasureFPS) {
205543e10145911bde6ac8c3f14fd46611a13c76f8b9reed@google.com        title.appendf(" %8.3f ms", fMeasureFPS_Time / (float)FPS_REPEAT_COUNT);
20562eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
2057a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    if (SampleView::IsSampleView(view)) {
2058b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        switch (fPipeState) {
2059b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            case SkOSMenu::kOnState:
2060b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                title.prepend("<Pipe> ");
2061b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
2062b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            case SkOSMenu::kMixedState:
2063b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                title.prepend("<Tiled Pipe> ");
2064b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
20654605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2066b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            default:
2067b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
2068b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2069a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com        title.prepend("! ");
2070a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    }
20712eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2072cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
207382502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com    if (IsGpuDeviceType(fDeviceType) &&
20744750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com        NULL != fDevManager &&
207582502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        fDevManager->getGrRenderTarget() &&
20761195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fDevManager->getGrRenderTarget()->numSamples() > 0) {
20771195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        title.appendf(" [MSAA: %d]",
20781195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                       fDevManager->getGrRenderTarget()->numSamples());
20791195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
2080cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
20811195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
20828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->setTitle(title.c_str());
20838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
20848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onSizeChange() {
20868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::onSizeChange();
20874605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
20888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
20898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* view = iter.next();
20908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
20912e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
20928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // rebuild our clippath
20938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar W = this->width();
20958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar H = this->height();
20962e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
20978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.reset();
20988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0
20998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkRect r;
21018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
21028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
21038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fClipPath.addRect(r);
21048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
21058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
21068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRect r;
21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(0, 0, W, H);
21088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCCW_Direction);
21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(W/4, H/4, W*3/4, H*3/4);
21108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCW_Direction);
21118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
21128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
21132e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
21142c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterX = SkScalarHalf(this->width());
21152c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterY = SkScalarHalf(this->height());
21162c8208f3a444098aee562f5a1ef620142807eda2Scroggo
211756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
2118b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // FIXME: The first draw after a size change does not work on Android, so
2119b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // we post an invalidate.
212062b65b0913566381db468277de07e5dd2a9237caScroggo    this->postInvalDelay();
2121716a0387ca197ca728ba691f3d812d4252c0f10bScroggo#endif
21228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();    // to refresh our config
2123098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    fDevManager->windowSizeChanged(this);
2124bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org
2125bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    if (fTilingMode != kNo_Tiling && SampleView::IsSampleView(view)) {
2126bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org        ((SampleView*)view)->onTileSizeChanged(this->tileSize());
2127bbe43a9ce0513d37cbd5dca583c391b7b1e39b3acommit-bot@chromium.org    }
21288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
21298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
21308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
21318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2132a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.comstatic const char is_sample_view_tag[] = "sample-is-sample-view";
21332eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic const char repeat_count_tag[] = "sample-set-repeat-count";
21340faac1e8579088a39f38d02ff675f14d7deb608dreed@google.comstatic const char set_use_pipe_tag[] = "sample-set-use-pipe";
21352eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2136a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.combool SampleView::IsSampleView(SkView* view) {
2137a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    SkEvent evt(is_sample_view_tag);
2138a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    return view->doQuery(&evt);
2139a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com}
2140a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com
2141f21833999d90ad9c8c584cff3238797b39cfc00breed@google.combool SampleView::SetRepeatDraw(SkView* view, int count) {
21422eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    SkEvent evt(repeat_count_tag);
21432eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    evt.setFast32(count);
2144f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    return view->doEvent(evt);
21452eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21462eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2147b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.combool SampleView::SetUsePipe(SkView* view, SkOSMenu::TriState state) {
2148b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    SkEvent evt;
2149b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    evt.setS32(set_use_pipe_tag, state);
21500faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    return view->doEvent(evt);
21510faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com}
21520faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com
21532eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgbool SampleView::onEvent(const SkEvent& evt) {
21542eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (evt.isType(repeat_count_tag)) {
21552eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        fRepeatCount = evt.getFast32();
21562eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        return true;
21572eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
21584d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
2159b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    int32_t pipeHolder;
2160b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (evt.findS32(set_use_pipe_tag, &pipeHolder)) {
2161b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fPipeState = static_cast<SkOSMenu::TriState>(pipeHolder);
21620faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com        return true;
21630faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
21644d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
21652eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return this->INHERITED::onEvent(evt);
21662eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21672eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
21682eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgbool SampleView::onQuery(SkEvent* evt) {
2169a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    if (evt->isType(is_sample_view_tag)) {
2170a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com        return true;
2171a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    }
21722eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return this->INHERITED::onQuery(evt);
21732eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21742eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
217564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
217664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comclass SimplePC : public SkGPipeController {
217764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.compublic:
217864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SimplePC(SkCanvas* target);
217964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    ~SimplePC();
21804605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
218164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    virtual void* requestBlock(size_t minRequest, size_t* actual);
218264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    virtual void notifyWritten(size_t bytes);
218364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
218464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comprivate:
2185961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    SkGPipeReader   fReader;
2186961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    void*           fBlock;
2187961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    size_t          fBlockSize;
2188961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    size_t          fBytesWritten;
2189961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    int             fAtomsWritten;
219064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkGPipeReader::Status   fStatus;
219164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
219264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    size_t        fTotalWritten;
219364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com};
219464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
219564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comSimplePC::SimplePC(SkCanvas* target) : fReader(target) {
219664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlock = NULL;
219764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlockSize = fBytesWritten = 0;
219864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fStatus = SkGPipeReader::kDone_Status;
219964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fTotalWritten = 0;
2200961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    fAtomsWritten = 0;
220174b7ffda687c66d46ac3cfa4f2baedd4c62e3fbescroggo@google.com    fReader.setBitmapDecoder(&SkImageDecoder::DecodeMemory);
220264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
220364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
220464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comSimplePC::~SimplePC() {
220564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com//    SkASSERT(SkGPipeReader::kDone_Status == fStatus);
22060faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    if (fTotalWritten) {
2207b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten,
2208b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                 fAtomsWritten, fStatus);
2209db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_FILE
2210b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        //File is open in append mode
2211b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        FILE* f = fopen(FILE_PATH, "ab");
2212b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkASSERT(f != NULL);
2213b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f);
2214b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fclose(f);
2215db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
2216db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef PIPE_NET
2217b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (fAtomsWritten > 1 && fTotalWritten > 4) { //ignore done
2218b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            gServer.acceptConnections();
2219b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            gServer.writePacket(fBlock, fTotalWritten);
2220b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2221db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
22220faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
2223db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    sk_free(fBlock);
222464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
222564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
222664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comvoid* SimplePC::requestBlock(size_t minRequest, size_t* actual) {
222764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    sk_free(fBlock);
222864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
222964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlockSize = minRequest * 4;
223064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlock = sk_malloc_throw(fBlockSize);
223164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBytesWritten = 0;
223264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    *actual = fBlockSize;
223364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    return fBlock;
223464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
223564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
223664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comvoid SimplePC::notifyWritten(size_t bytes) {
223764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkASSERT(fBytesWritten + bytes <= fBlockSize);
223864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes);
223964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkASSERT(SkGPipeReader::kError_Status != fStatus);
224064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBytesWritten += bytes;
224164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fTotalWritten += bytes;
22424605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2243961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    fAtomsWritten += 1;
224464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
224564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
2246db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleView::draw(SkCanvas* canvas) {
2247b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (SkOSMenu::kOffState == fPipeState) {
2248b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        this->INHERITED::draw(canvas);
2249b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    } else {
2250db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        SkGPipeWriter writer;
2251db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        SimplePC controller(canvas);
2252b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        TiledPipeController tc(canvas->getDevice()->accessBitmap(false),
225374b7ffda687c66d46ac3cfa4f2baedd4c62e3fbescroggo@google.com                               &SkImageDecoder::DecodeMemory,
2254b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                               &canvas->getTotalMatrix());
2255b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkGPipeController* pc;
2256b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (SkOSMenu::kMixedState == fPipeState) {
2257b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            pc = &tc;
2258b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        } else {
2259b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            pc = &controller;
2260b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2261dde0956375e87027df2fdd80d430dd819c217aacreed@google.com        uint32_t flags = SkGPipeWriter::kCrossProcess_Flag;
22624605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2263b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        canvas = writer.startRecording(pc, flags);
2264db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        //Must draw before controller goes out of scope and sends data
2265db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->INHERITED::draw(canvas);
2266ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        //explicitly end recording to ensure writer is flushed before the memory
2267ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        //is freed in the deconstructor of the controller
2268ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        writer.endRecording();
22690faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
2270db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
22714d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
2272db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleView::onDraw(SkCanvas* canvas) {
227381e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com    this->onDrawBackground(canvas);
227481e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com
22752eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    for (int i = 0; i < fRepeatCount; i++) {
227685cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        SkAutoCanvasRestore acr(canvas, true);
227785cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        this->onDrawContent(canvas);
22782eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
22792eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
22802eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
22812eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgvoid SampleView::onDrawBackground(SkCanvas* canvas) {
2282f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    canvas->drawColor(fBGColor);
22832eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
22842eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
22852eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
22862eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2287f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comtemplate <typename T> void SkTBSort(T array[], int count) {
2288f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 1; i < count - 1; i++) {
2289f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        bool didSwap = false;
2290f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = count - 1; j > i; --j) {
2291f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (array[j] < array[j-1]) {
2292f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                T tmp(array[j-1]);
2293f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j-1] = array[j];
2294f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j] = tmp;
2295f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                didSwap = true;
2296f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
2297f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2298f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (!didSwap) {
2299f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
2300f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2301f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
23022e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2303f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int k = 0; k < count - 1; k++) {
2304f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkASSERT(!(array[k+1] < array[k]));
2305f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2306f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2307f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2308f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkRandom.h"
2309f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2310e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic void rand_rect(SkIRect* rect, SkRandom& rand) {
2311f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int bits = 8;
2312f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int shift = 32 - bits;
2313f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
2314f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com              rand.nextU() >> shift, rand.nextU() >> shift);
2315f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->sort();
2316f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2317f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2318f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void dumpRect(const SkIRect& r) {
2319f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf(" { %d, %d, %d, %d },\n",
2320f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fLeft, r.fTop,
2321f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fRight, r.fBottom);
2322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2323f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2324f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test_rects(const SkIRect rect[], int count) {
2325f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRegion rgn0, rgn1;
2326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 0; i < count; i++) {
2328f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        rgn0.op(rect[i], SkRegion::kUnion_Op);
2329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com     //   dumpRect(rect[i]);
2330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2331f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rgn1.setRects(rect, count);
2332f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (rgn0 != rgn1) {
2334f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
2335f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int i = 0; i < count; i++) {
2336f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            dumpRect(rect[i]);
2337f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2338f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
2339f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2340f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2341f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2342f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test() {
2343f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    size_t i;
2344f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2345f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r0[] = {
2346f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 1 },
2347f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 2, 3, 3 },
2348f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2349f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r1[] = {
2350f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 3 },
2351f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 1, 1, 2, 2 },
2352f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 0, 3, 3 },
2353f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2354f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r2[] = {
2355f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 2 },
2356f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 1, 3, 3 },
2357f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 4, 0, 5, 1 },
2358f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 6, 0, 7, 4 },
2359f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2360f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2361f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const struct {
2362f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const SkIRect* fRects;
2363f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        int            fCount;
2364f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } gRecs[] = {
2365f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r0, SK_ARRAY_COUNT(r0) },
2366f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r1, SK_ARRAY_COUNT(r1) },
2367f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r2, SK_ARRAY_COUNT(r2) },
2368f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2369f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2370f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
2371f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(gRecs[i].fRects, gRecs[i].fCount);
2372f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
23732e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2374e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
2375f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < 10000; i++) {
2376f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkRegion rgn0, rgn1;
2377f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2378f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const int N = 8;
2379f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkIRect rect[N];
2380f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = 0; j < N; j++) {
2381f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rand_rect(&rect[j], rand);
2382f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2383f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(rect, N);
2384f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2385f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2386f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
238702939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
238802939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comSkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
238978b8253c0a389a484e15439722e35a1658eb3b01senorblanco@chromium.orgSkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
239002939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    if (false) { // avoid bit rot, suppress warning
239102939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com        test();
239202939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    }
2393098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    return new SampleWindow(hwnd, argc, argv, NULL);
23948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
23958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
239602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
239702939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid get_preferred_size(int* x, int* y, int* width, int* height);
23988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid get_preferred_size(int* x, int* y, int* width, int* height) {
23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *x = 10;
24008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *y = 50;
24018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *width = 640;
24028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *height = 480;
24038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
24048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24055987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#ifdef SK_BUILD_FOR_IOS
24065987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comvoid save_args(int argc, char *argv[]) {
24075987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
24085987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
24095987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
241002939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
241102939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid application_init();
24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_init() {
24138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    setenv("ANDROID_ROOT", "../../../data", 0);
2414e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#ifdef SK_BUILD_FOR_MAC
24158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    setenv("ANDROID_ROOT", "/android/device/data", 0);
2416e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#endif
24172fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Init();
24182fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Init();
24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
24208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
242102939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
242202939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid application_term();
24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_term() {
24242fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Term();
24252fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Term();
24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2427