1 /*
2  * Copyright 2011 Skia
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SampleApp_DEFINED
9 #define SampleApp_DEFINED
10 
11 #include "SkOSMenu.h"
12 #include "SkPath.h"
13 #include "SkPicture.h"
14 #include "SkPictureRecorder.h"
15 #include "SkScalar.h"
16 #include "SkStream.h"
17 #include "SkSurface.h"
18 #include "SkTDArray.h"
19 #include "SkTouchGesture.h"
20 #include "SkWindow.h"
21 #include "timer/Timer.h"
22 
23 #include "SkPipe.h"
24 
25 #if SK_SUPPORT_GPU
26 #include "GrContextOptions.h"
27 #endif
28 
29 class GrContext;
30 class GrRenderTarget;
31 
32 class SkCanvas;
33 class SkData;
34 class SkDocument;
35 class SkEvent;
36 class SkTypeface;
37 class SkViewFactory;
38 
39 class SampleWindow : public SkOSWindow {
40     SkTDArray<const SkViewFactory*> fSamples;
41 public:
42     enum DeviceType {
43         kRaster_DeviceType,
44 #if SK_SUPPORT_GPU
45         kGPU_DeviceType,
46 #if SK_ANGLE
47         kANGLE_DeviceType,
48 #endif // SK_ANGLE
49 #endif // SK_SUPPORT_GPU
50         kDeviceTypeCnt
51     };
52 
IsGpuDeviceType(DeviceType devType)53     static bool IsGpuDeviceType(DeviceType devType) {
54     #if SK_SUPPORT_GPU
55         switch (devType) {
56             case kGPU_DeviceType:
57     #if SK_ANGLE
58             case kANGLE_DeviceType:
59     #endif // SK_ANGLE
60                 return true;
61             default:
62                 return false;
63         }
64     #endif // SK_SUPPORT_GPU
65         return false;
66     }
67 
68     /**
69      * SampleApp ports can subclass this manager class if they want to:
70      *      * filter the types of devices supported
71      *      * customize plugging of SkBaseDevice objects into an SkCanvas
72      *      * customize publishing the results of draw to the OS window
73      *      * manage GrContext / GrRenderTarget lifetimes
74      */
75     class DeviceManager : public SkRefCnt {
76     public:
77         struct BackendOptions {
78 #if SK_SUPPORT_GPU
79             GrContextOptions   fGrContextOptions;
80             int                fMSAASampleCount;
81             bool               fDeepColor;
82 #endif
83         };
84 
85         virtual void setUpBackend(SampleWindow* win, const BackendOptions&) = 0;
86 
87         virtual void tearDownBackend(SampleWindow* win) = 0;
88 
89         // called before drawing. should install correct device
90         // type on the canvas. Will skip drawing if returns false.
91         virtual sk_sp<SkSurface> makeSurface(DeviceType dType, SampleWindow* win) = 0;
92 
93         // called after drawing, should get the results onto the
94         // screen.
95         virtual void publishCanvas(DeviceType dType,
96                                    SkCanvas* canvas,
97                                    SampleWindow* win) = 0;
98 
99         // called when window changes size, guaranteed to be called
100         // at least once before first draw (after init)
101         virtual void windowSizeChanged(SampleWindow* win) = 0;
102 
103         // return the GrContext backing gpu devices (nullptr if not built with GPU support)
104         virtual GrContext* getGrContext() = 0;
105 
106         // return the GrRenderTarget backing gpu devices (nullptr if not built with GPU support)
107         virtual int numColorSamples() const = 0;
108 
109         // return the color depth of the output device
110         virtual int getColorBits() = 0;
111 
112     private:
113         typedef SkRefCnt INHERITED;
114     };
115 
116     SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
117     ~SampleWindow() override;
118 
makeSurface()119     sk_sp<SkSurface> makeSurface() override {
120         sk_sp<SkSurface> surface;
121         if (fDevManager) {
122             surface = fDevManager->makeSurface(fDeviceType, this);
123         }
124         if (!surface) {
125             surface = this->INHERITED::makeSurface();
126         }
127         return surface;
128     }
129 
130     void draw(SkCanvas*) override;
131 
132     void setDeviceType(DeviceType type);
133     void setDeviceColorType(SkColorType, sk_sp<SkColorSpace>);
134     void toggleRendering();
135     void toggleSlideshow();
136     void toggleFPS();
137     void showOverview();
138     void toggleDistanceFieldFonts();
139     void setPixelGeometry(int pixelGeometryIndex);
140 
getGrContext()141     GrContext* getGrContext() const { return fDevManager->getGrContext(); }
142 
143     void setZoomCenter(float x, float y);
144     void changeZoomLevel(float delta);
145     void changeOffset(SkVector delta);
146     bool nextSample();
147     bool previousSample();
148     bool goToSample(int i);
149     SkString getSampleTitle(int i);
150     int  sampleCount();
151     bool handleTouch(int ownerId, float x, float y,
152             SkView::Click::State state);
153     void saveToPdf();
154     void postInvalDelay();
155 
getDeviceType()156     DeviceType getDeviceType() const { return fDeviceType; }
getColorConfigIndex()157     int getColorConfigIndex() const { return fColorConfigIndex; }
158 
159 protected:
160     void onDraw(SkCanvas* canvas) override;
161     bool onHandleKey(SkKey key) override;
162     bool onHandleChar(SkUnichar) override;
163     void onSizeChange() override;
164 
165     SkCanvas* beforeChildren(SkCanvas*) override;
166     void afterChildren(SkCanvas*) override;
167     void beforeChild(SkView* child, SkCanvas* canvas) override;
168 
169     bool onEvent(const SkEvent& evt) override;
170     bool onQuery(SkEvent* evt) override;
171 
172     virtual bool onDispatchClick(int x, int y, Click::State, void* owner,
173                                  unsigned modi) override;
174     bool onClick(Click* click) override;
175     virtual Click* onFindClickHandler(SkScalar x, SkScalar y,
176                                       unsigned modi) override;
177 
178 private:
179     class DefaultDeviceManager;
180 
181     int fCurrIndex;
182 
183     std::unique_ptr<SkDynamicMemoryWStream> fPipeStream;
184     SkPipeSerializer        fPipeSerializer;
185     SkPipeDeserializer      fPipeDeserializer;
186 
187     SkPictureRecorder fRecorder;
188     std::unique_ptr<SkCanvas> fFlagsFilterCanvas;
189     SkPath fClipPath;
190 
191     SkTouchGesture fGesture;
192     SkScalar fZoomLevel;
193     SkScalar fZoomScale;
194     SkVector fOffset;
195 
196     DeviceType fDeviceType;
197     DeviceManager* fDevManager;
198 
199     bool fSaveToPdf;
200     bool fSaveToSKP;
201     sk_sp<SkDocument> fPDFDocument;
202 
203     bool fUseClip;
204     bool fUsePicture;
205     bool fAnimating;
206     bool fRotate;
207     bool fPerspAnim;
208     bool fRequestGrabImage;
209     bool fMeasureFPS;
210     bool fUseDeferredCanvas;
211     WallTimer fTimer;
212     double fMeasureFPS_Time;
213     bool fMagnify;
214     int fTilingMode;
215 
216     // The following are for the 'fatbits' drawing
217     // Latest position of the mouse.
218     int fMouseX, fMouseY;
219     int fFatBitsScale;
220     // Used by the text showing position and color values.
221     sk_sp<SkTypeface> fTypeface;
222     bool fShowZoomer;
223 
224     SkOSMenu::TriState fLCDState;
225     SkOSMenu::TriState fAAState;
226     SkOSMenu::TriState fSubpixelState;
227     int fHintingState;
228     int fPixelGeometryIndex;
229     int fFilterQualityIndex;
230     unsigned   fFlipAxis;
231 
232     DeviceManager::BackendOptions fBackendOptions;
233 
234     int fColorConfigIndex;
235 
236     SkScalar fZoomCenterX, fZoomCenterY;
237 
238     //Stores global settings
239     SkOSMenu* fAppMenu; // We pass ownership to SkWindow, when we call addMenu
240     //Stores slide specific settings
241     SkOSMenu* fSlideMenu; // We pass ownership to SkWindow, when we call addMenu
242 
243     void loadView(SkView*);
244     void updateTitle();
245     bool getRawTitle(SkString*);
246 
247     bool zoomIn();
248     bool zoomOut();
249     void updatePointer(int x, int y);
250     void magnify(SkCanvas* canvas);
251     void showZoomer(SkCanvas* canvas);
252     void updateMatrix();
253     void postAnimatingEvent();
254     int findByTitle(const char*);
255     void listTitles();
256     SkSize tileSize() const;
257     bool sendAnimatePulse();
258 
259     typedef SkOSWindow INHERITED;
260 };
261 
262 #endif
263