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 "SkTDArray.h"
17 #include "SkTouchGesture.h"
18 #include "SkWindow.h"
19 
20 class GrContext;
21 class GrRenderTarget;
22 
23 class SkCanvas;
24 class SkData;
25 class SkDeferredCanvas;
26 class SkDocument;
27 class SkEvent;
28 class SkTypeface;
29 class SkViewFactory;
30 
31 class SampleWindow : public SkOSWindow {
32     SkTDArray<const SkViewFactory*> fSamples;
33 public:
34     enum DeviceType {
35         kRaster_DeviceType,
36         kPicture_DeviceType,
37 #if SK_SUPPORT_GPU
38         kGPU_DeviceType,
39 #if SK_ANGLE
40         kANGLE_DeviceType,
41 #endif // SK_ANGLE
42 #endif // SK_SUPPORT_GPU
43         kDeferred_DeviceType,
44         kDeviceTypeCnt
45     };
46 
IsGpuDeviceType(DeviceType devType)47     static bool IsGpuDeviceType(DeviceType devType) {
48     #if SK_SUPPORT_GPU
49         switch (devType) {
50             case kGPU_DeviceType:
51     #if SK_ANGLE
52             case kANGLE_DeviceType:
53     #endif // SK_ANGLE
54                 return true;
55             default:
56                 return false;
57         }
58     #endif // SK_SUPPORT_GPU
59         return false;
60     }
61 
62     /**
63      * SampleApp ports can subclass this manager class if they want to:
64      *      * filter the types of devices supported
65      *      * customize plugging of SkBaseDevice objects into an SkCanvas
66      *      * customize publishing the results of draw to the OS window
67      *      * manage GrContext / GrRenderTarget lifetimes
68      */
69     class DeviceManager : public SkRefCnt {
70     public:
71         SK_DECLARE_INST_COUNT(DeviceManager)
72 
73         virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) = 0;
74 
75         virtual void tearDownBackend(SampleWindow* win) = 0;
76 
77         // called before drawing. should install correct device
78         // type on the canvas. Will skip drawing if returns false.
79         virtual SkSurface* createSurface(DeviceType dType, SampleWindow* win) = 0;
80 
81         // called after drawing, should get the results onto the
82         // screen.
83         virtual void publishCanvas(DeviceType dType,
84                                    SkCanvas* canvas,
85                                    SampleWindow* win) = 0;
86 
87         // called when window changes size, guaranteed to be called
88         // at least once before first draw (after init)
89         virtual void windowSizeChanged(SampleWindow* win) = 0;
90 
91         // return the GrContext backing gpu devices (NULL if not built with GPU support)
92         virtual GrContext* getGrContext() = 0;
93 
94         // return the GrRenderTarget backing gpu devices (NULL if not built with GPU support)
95         virtual GrRenderTarget* getGrRenderTarget() = 0;
96     private:
97         typedef SkRefCnt INHERITED;
98     };
99 
100     SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
101     virtual ~SampleWindow();
102 
createSurface()103     SkSurface* createSurface() override {
104         SkSurface* surface = NULL;
105         if (fDevManager) {
106             surface = fDevManager->createSurface(fDeviceType, this);
107         }
108         if (NULL == surface) {
109             surface = this->INHERITED::createSurface();
110         }
111         return surface;
112     }
113 
114     void draw(SkCanvas*) override;
115 
116     void setDeviceType(DeviceType type);
117     void toggleRendering();
118     void toggleSlideshow();
119     void toggleFPS();
120     void showOverview();
121     void toggleDistanceFieldFonts();
122 
getGrContext()123     GrContext* getGrContext() const { return fDevManager->getGrContext(); }
124 
125     void setZoomCenter(float x, float y);
126     void changeZoomLevel(float delta);
127     bool nextSample();
128     bool previousSample();
129     bool goToSample(int i);
130     SkString getSampleTitle(int i);
131     int  sampleCount();
132     bool handleTouch(int ownerId, float x, float y,
133             SkView::Click::State state);
134     void saveToPdf();
135     void postInvalDelay();
136 
getDeviceType()137     DeviceType getDeviceType() const { return fDeviceType; }
138 
139 protected:
140     void onDraw(SkCanvas* canvas) override;
141     bool onHandleKey(SkKey key) override;
142     bool onHandleChar(SkUnichar) override;
143     void onSizeChange() override;
144 
145     SkCanvas* beforeChildren(SkCanvas*) override;
146     void afterChildren(SkCanvas*) override;
147     void beforeChild(SkView* child, SkCanvas* canvas) override;
148     void afterChild(SkView* child, SkCanvas* canvas) override;
149 
150     bool onEvent(const SkEvent& evt) override;
151     bool onQuery(SkEvent* evt) override;
152 
153     virtual bool onDispatchClick(int x, int y, Click::State, void* owner,
154                                  unsigned modi) override;
155     bool onClick(Click* click) override;
156     virtual Click* onFindClickHandler(SkScalar x, SkScalar y,
157                                       unsigned modi) override;
158 
159 private:
160     class DefaultDeviceManager;
161 
162     int fCurrIndex;
163 
164     SkPictureRecorder fRecorder;
165     SkAutoTDelete<SkSurface> fDeferredSurface;
166     SkAutoTDelete<SkDeferredCanvas> fDeferredCanvas;
167     SkPath fClipPath;
168 
169     SkTouchGesture fGesture;
170     SkScalar fZoomLevel;
171     SkScalar fZoomScale;
172 
173     DeviceType fDeviceType;
174     DeviceManager* fDevManager;
175 
176     bool fSaveToPdf;
177     SkAutoTUnref<SkDocument> fPDFDocument;
178 
179     bool fUseClip;
180     bool fAnimating;
181     bool fRotate;
182     bool fPerspAnim;
183     bool fRequestGrabImage;
184     bool fMeasureFPS;
185     SkMSec fMeasureFPS_Time;
186     SkMSec fMeasureFPS_StartTime;
187     bool fMagnify;
188     int fTilingMode;
189 
190 
191     SkOSMenu::TriState fPipeState;  // Mixed uses a tiled pipe
192                                     // On uses a normal pipe
193                                     // Off uses no pipe
194     int  fUsePipeMenuItemID;
195 
196     // The following are for the 'fatbits' drawing
197     // Latest position of the mouse.
198     int fMouseX, fMouseY;
199     int fFatBitsScale;
200     // Used by the text showing position and color values.
201     SkTypeface* fTypeface;
202     bool fShowZoomer;
203 
204     SkOSMenu::TriState fLCDState;
205     SkOSMenu::TriState fAAState;
206     SkOSMenu::TriState fSubpixelState;
207     int fHintingState;
208     int fFilterQualityIndex;
209     unsigned   fFlipAxis;
210 
211     int fMSAASampleCount;
212 
213     int fScrollTestX, fScrollTestY;
214     SkScalar fZoomCenterX, fZoomCenterY;
215 
216     //Stores global settings
217     SkOSMenu* fAppMenu; // We pass ownership to SkWindow, when we call addMenu
218     //Stores slide specific settings
219     SkOSMenu* fSlideMenu; // We pass ownership to SkWindow, when we call addMenu
220 
221     int fTransitionNext;
222     int fTransitionPrev;
223 
224     void loadView(SkView*);
225     void updateTitle();
226     bool getRawTitle(SkString*);
227 
228     bool zoomIn();
229     bool zoomOut();
230     void updatePointer(int x, int y);
231     void magnify(SkCanvas* canvas);
232     void showZoomer(SkCanvas* canvas);
233     void updateMatrix();
234     void postAnimatingEvent();
235     void installDrawFilter(SkCanvas*);
236     int findByTitle(const char*);
237     void listTitles();
238     SkSize tileSize() const;
239     bool sendAnimatePulse();
240 
241     typedef SkOSWindow INHERITED;
242 };
243 
244 #endif
245