1 /* 2 * Copyright 2016 Google Inc. 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 Window_DEFINED 9 #define Window_DEFINED 10 11 #include "include/core/SkRect.h" 12 #include "include/core/SkTypes.h" 13 #include "include/private/base/SkTDArray.h" 14 #include "tools/skui/InputState.h" 15 #include "tools/skui/Key.h" 16 #include "tools/skui/ModifierKey.h" 17 18 #include <functional> 19 #include <memory> 20 21 class GrDirectContext; 22 class SkCanvas; 23 class SkSurface; 24 class SkSurfaceProps; 25 class SkString; 26 27 namespace skgpu::graphite { 28 class Context; 29 class Recorder; 30 } 31 32 namespace skwindow { 33 class DisplayParams; 34 class WindowContext; 35 } 36 37 namespace sk_app { 38 39 class Window { 40 public: 41 virtual ~Window(); 42 43 virtual void setTitle(const char*) = 0; 44 virtual void show() = 0; 45 46 // JSON-formatted UI state for Android. Do nothing by default setUIState(const char *)47 virtual void setUIState(const char*) {} 48 49 // Interface to the system clipboard. Only implemented on UNIX. getClipboardText()50 virtual const char* getClipboardText() { return nullptr; } setClipboardText(const char *)51 virtual void setClipboardText(const char*) {} 52 53 // Schedules an invalidation event for window if one is not currently pending. 54 // Make sure that either onPaint or markInvalReceived is called when the client window consumes 55 // the the inval event. They unset fIsContentInvalided which allow future onInval. 56 void inval(); 57 scaleContentToFit()58 virtual bool scaleContentToFit() const { return false; } 59 60 enum BackendType { 61 kNativeGL_BackendType, 62 kANGLE_BackendType, 63 kGraphiteDawn_BackendType, 64 kVulkan_BackendType, 65 kGraphiteVulkan_BackendType, 66 kMetal_BackendType, 67 kGraphiteMetal_BackendType, 68 kDirect3D_BackendType, 69 kRaster_BackendType, 70 }; 71 72 virtual bool attach(BackendType) = 0; 73 void detach(); 74 75 // input handling 76 77 class Layer { 78 public: Layer()79 Layer() : fActive(true) {} 80 virtual ~Layer() = default; 81 getActive()82 bool getActive() { return fActive; } setActive(bool active)83 void setActive(bool active) { fActive = active; } 84 85 // return value of 'true' means 'I have handled this event' onBackendCreated()86 virtual void onBackendCreated() {} onAttach(Window * window)87 virtual void onAttach(Window* window) {} onChar(SkUnichar c,skui::ModifierKey)88 virtual bool onChar(SkUnichar c, skui::ModifierKey) { return false; } onKey(skui::Key,skui::InputState,skui::ModifierKey)89 virtual bool onKey(skui::Key, skui::InputState, skui::ModifierKey) { return false; } onMouse(int x,int y,skui::InputState,skui::ModifierKey)90 virtual bool onMouse(int x, int y, skui::InputState, skui::ModifierKey) { return false; } onMouseWheel(float delta,int x,int y,skui::ModifierKey)91 virtual bool onMouseWheel(float delta, int x, int y, skui::ModifierKey) { return false; } onTouch(intptr_t owner,skui::InputState,float x,float y)92 virtual bool onTouch(intptr_t owner, skui::InputState, float x, float y) { return false; } 93 // Platform-detected gesture events onFling(skui::InputState state)94 virtual bool onFling(skui::InputState state) { return false; } onPinch(skui::InputState state,float scale,float x,float y)95 virtual bool onPinch(skui::InputState state, float scale, float x, float y) { return false; } onUIStateChanged(const SkString & stateName,const SkString & stateValue)96 virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {} onPrePaint()97 virtual void onPrePaint() {} onPaint(SkSurface *)98 virtual void onPaint(SkSurface*) {} onResize(int width,int height)99 virtual void onResize(int width, int height) {} 100 101 private: 102 friend class Window; 103 bool fActive; 104 }; 105 pushLayer(Layer * layer)106 void pushLayer(Layer* layer) { 107 layer->onAttach(this); 108 fLayers.push_back(layer); 109 } 110 111 void onBackendCreated(); 112 bool onChar(SkUnichar c, skui::ModifierKey modifiers); 113 bool onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers); 114 bool onMouse(int x, int y, skui::InputState state, skui::ModifierKey modifiers); 115 bool onMouseWheel(float delta, int x, int y, skui::ModifierKey modifiers); 116 bool onTouch(intptr_t owner, skui::InputState state, float x, float y); // multi-owner = multi-touch 117 // Platform-detected gesture events 118 bool onFling(skui::InputState state); 119 bool onPinch(skui::InputState state, float scale, float x, float y); 120 void onUIStateChanged(const SkString& stateName, const SkString& stateValue); 121 void onPaint(); 122 void onResize(int width, int height); 123 void onActivate(bool isActive); 124 125 int width() const; 126 int height() const; scaleFactor()127 virtual float scaleFactor() const { return 1.0f; } 128 getRequestedDisplayParams()129 const skwindow::DisplayParams* getRequestedDisplayParams() { 130 return fRequestedDisplayParams.get(); 131 } 132 virtual void setRequestedDisplayParams(std::unique_ptr<const skwindow::DisplayParams>, 133 bool allowReattach = true); 134 135 // Actual parameters in effect, obtained from the native window. 136 int sampleCount() const; 137 int stencilBits() const; 138 139 // Returns null if there is not a GPU backend or if the backend is not yet created. 140 GrDirectContext* directContext() const; 141 skgpu::graphite::Context* graphiteContext() const; 142 skgpu::graphite::Recorder* graphiteRecorder() const; 143 144 using GpuTimerCallback = std::function<void(uint64_t ns)>; 145 146 // Does the backend of this window support GPU timers (for use with submitToGpu)? 147 bool supportsGpuTimer() const; 148 149 // Will snap a Recording and submit to the Context if using Graphite or flush and submit 150 // if using Ganesh. 151 void submitToGpu(GpuTimerCallback = {}); 152 153 protected: 154 Window(); 155 156 SkTDArray<Layer*> fLayers; 157 std::unique_ptr<const skwindow::DisplayParams> fRequestedDisplayParams; 158 bool fIsActive = true; 159 160 std::unique_ptr<skwindow::WindowContext> fWindowContext; 161 162 virtual void onInval() = 0; 163 164 // Uncheck fIsContentInvalided to allow future inval/onInval. 165 void markInvalProcessed(); 166 167 bool fIsContentInvalidated = false; // use this to avoid duplicate invalidate events 168 169 void visitLayers(const std::function<void(Layer*)>& visitor); 170 bool signalLayers(const std::function<bool(Layer*)>& visitor); 171 }; 172 173 namespace Windows { 174 Window* CreateNativeWindow(void* platformData); 175 } 176 177 } // namespace sk_app 178 #endif 179