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 #include "tools/sk_app/Window.h"
9
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkSurface.h"
12 #include "tools/window/WindowContext.h"
13
14 #if defined(SK_GANESH)
15 #include "include/gpu/GrDirectContext.h"
16 #include "include/gpu/GrRecordingContext.h"
17 #endif
18
19 namespace sk_app {
20
Window()21 Window::Window() {}
22
~Window()23 Window::~Window() {}
24
detach()25 void Window::detach() { fWindowContext = nullptr; }
26
visitLayers(const std::function<void (Layer *)> & visitor)27 void Window::visitLayers(const std::function<void(Layer*)>& visitor) {
28 for (int i = 0; i < fLayers.size(); ++i) {
29 if (fLayers[i]->fActive) {
30 visitor(fLayers[i]);
31 }
32 }
33 }
34
signalLayers(const std::function<bool (Layer *)> & visitor)35 bool Window::signalLayers(const std::function<bool(Layer*)>& visitor) {
36 for (int i = fLayers.size() - 1; i >= 0; --i) {
37 if (fLayers[i]->fActive && visitor(fLayers[i])) {
38 return true;
39 }
40 }
41 return false;
42 }
43
onBackendCreated()44 void Window::onBackendCreated() {
45 this->visitLayers([](Layer* layer) { layer->onBackendCreated(); });
46 }
47
onChar(SkUnichar c,skui::ModifierKey modifiers)48 bool Window::onChar(SkUnichar c, skui::ModifierKey modifiers) {
49 return this->signalLayers([=](Layer* layer) { return layer->onChar(c, modifiers); });
50 }
51
onKey(skui::Key key,skui::InputState state,skui::ModifierKey modifiers)52 bool Window::onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers) {
53 return this->signalLayers([=](Layer* layer) { return layer->onKey(key, state, modifiers); });
54 }
55
onMouse(int x,int y,skui::InputState state,skui::ModifierKey modifiers)56 bool Window::onMouse(int x, int y, skui::InputState state, skui::ModifierKey modifiers) {
57 return this->signalLayers([=](Layer* layer) { return layer->onMouse(x, y, state, modifiers); });
58 }
59
onMouseWheel(float delta,int x,int y,skui::ModifierKey modifiers)60 bool Window::onMouseWheel(float delta, int x, int y, skui::ModifierKey modifiers) {
61 return this->signalLayers(
62 [=](Layer* layer) { return layer->onMouseWheel(delta, x, y, modifiers); });
63 }
64
onTouch(intptr_t owner,skui::InputState state,float x,float y)65 bool Window::onTouch(intptr_t owner, skui::InputState state, float x, float y) {
66 return this->signalLayers([=](Layer* layer) { return layer->onTouch(owner, state, x, y); });
67 }
68
onFling(skui::InputState state)69 bool Window::onFling(skui::InputState state) {
70 return this->signalLayers([=](Layer* layer) { return layer->onFling(state); });
71 }
72
onPinch(skui::InputState state,float scale,float x,float y)73 bool Window::onPinch(skui::InputState state, float scale, float x, float y) {
74 return this->signalLayers([=](Layer* layer) { return layer->onPinch(state, scale, x, y); });
75 }
76
onUIStateChanged(const SkString & stateName,const SkString & stateValue)77 void Window::onUIStateChanged(const SkString& stateName, const SkString& stateValue) {
78 this->visitLayers([=](Layer* layer) { layer->onUIStateChanged(stateName, stateValue); });
79 }
80
onPaint()81 void Window::onPaint() {
82 if (!fWindowContext) {
83 return;
84 }
85 if (!fIsActive) {
86 return;
87 }
88 sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface();
89 if (backbuffer == nullptr) {
90 printf("no backbuffer!?\n");
91 // TODO: try recreating testcontext
92 return;
93 }
94
95 markInvalProcessed();
96
97 // draw into the canvas of this surface
98 this->visitLayers([](Layer* layer) { layer->onPrePaint(); });
99 this->visitLayers([=](Layer* layer) { layer->onPaint(backbuffer.get()); });
100
101 if (auto dContext = this->directContext()) {
102 dContext->flushAndSubmit(backbuffer.get(), GrSyncCpu::kNo);
103 }
104
105 fWindowContext->swapBuffers();
106 }
107
onResize(int w,int h)108 void Window::onResize(int w, int h) {
109 if (!fWindowContext) {
110 return;
111 }
112 fWindowContext->resize(w, h);
113 this->visitLayers([=](Layer* layer) { layer->onResize(w, h); });
114 }
115
onActivate(bool isActive)116 void Window::onActivate(bool isActive) {
117 if (fWindowContext) {
118 fWindowContext->activate(isActive);
119 }
120 fIsActive = isActive;
121 }
122
width() const123 int Window::width() const {
124 if (!fWindowContext) {
125 return 0;
126 }
127 return fWindowContext->width();
128 }
129
height() const130 int Window::height() const {
131 if (!fWindowContext) {
132 return 0;
133 }
134 return fWindowContext->height();
135 }
136
setRequestedDisplayParams(const DisplayParams & params,bool)137 void Window::setRequestedDisplayParams(const DisplayParams& params, bool /* allowReattach */) {
138 fRequestedDisplayParams = params;
139 if (fWindowContext) {
140 fWindowContext->setDisplayParams(fRequestedDisplayParams);
141 }
142 }
143
sampleCount() const144 int Window::sampleCount() const {
145 if (!fWindowContext) {
146 return 0;
147 }
148 return fWindowContext->sampleCount();
149 }
150
stencilBits() const151 int Window::stencilBits() const {
152 if (!fWindowContext) {
153 return -1;
154 }
155 return fWindowContext->stencilBits();
156 }
157
directContext() const158 GrDirectContext* Window::directContext() const {
159 if (!fWindowContext) {
160 return nullptr;
161 }
162 return fWindowContext->directContext();
163 }
164
graphiteContext() const165 skgpu::graphite::Context* Window::graphiteContext() const {
166 #if defined(SK_GRAPHITE)
167 if (!fWindowContext) {
168 return nullptr;
169 }
170 return fWindowContext->graphiteContext();
171 #else
172 return nullptr;
173 #endif
174 }
175
graphiteRecorder() const176 skgpu::graphite::Recorder* Window::graphiteRecorder() const {
177 #if defined(SK_GRAPHITE)
178 if (!fWindowContext) {
179 return nullptr;
180 }
181 return fWindowContext->graphiteRecorder();
182 #else
183 return nullptr;
184 #endif
185 }
186
187 #if defined(SK_GRAPHITE)
snapRecordingAndSubmit()188 void Window::snapRecordingAndSubmit() {
189 if (fWindowContext) {
190 fWindowContext->snapRecordingAndSubmit();
191 }
192 }
193 #endif
194
inval()195 void Window::inval() {
196 if (!fWindowContext) {
197 return;
198 }
199 if (!fIsContentInvalidated) {
200 fIsContentInvalidated = true;
201 onInval();
202 }
203 }
204
markInvalProcessed()205 void Window::markInvalProcessed() {
206 fIsContentInvalidated = false;
207 }
208
209 } // namespace sk_app
210