}
void ImageSlide::draw(SkCanvas* canvas) {
+ SkASSERT(fImage);
canvas->drawImage(fImage, 0, 0);
}
SampleSlide::~SampleSlide() {}
void SampleSlide::draw(SkCanvas* canvas) {
+ SkASSERT(fView);
fView->draw(canvas);
}
void SampleSlide::load(SkScalar winWidth, SkScalar winHeight) {
- fView = (*fViewFactory)();
+ fView.reset((*fViewFactory)());
fView->setVisibleP(true);
fView->setClipToBounds(false);
fView->setSize(winWidth, winHeight);
}
void SampleSlide::unload() {
- fView->unref();
- fView = nullptr;
+ fView.reset();
}
bool SampleSlide::onChar(SkUnichar c) {
+ if (!fView) {
+ return false;
+ }
SkEvent evt(gCharEvtName);
evt.setFast32(c);
return fView->doQuery(&evt);
void load(SkScalar winWidth, SkScalar winHeight) override;
void unload() override;
bool animate(const SkAnimTimer& timer) override {
- if (SampleView::IsSampleView(fView)) {
- return ((SampleView*)fView)->animate(timer);
+ if (fView && SampleView::IsSampleView(fView.get())) {
+ return ((SampleView*)fView.get())->animate(timer);
}
return false;
}
private:
const SkViewFactory* fViewFactory;
- SkView* fView;
+ sk_sp<SkView> fView;
};
#endif
return new Viewer(argc, argv, platformData);
}
+static void on_backend_created_func(void* userData) {
+ Viewer* vv = reinterpret_cast<Viewer*>(userData);
+
+ return vv->onBackendCreated();
+}
+
static void on_paint_handler(SkCanvas* canvas, void* userData) {
Viewer* vv = reinterpret_cast<Viewer*>(userData);
Viewer::Viewer(int argc, char** argv, void* platformData)
: fCurrentMeasurement(0)
- , fSetupFirstFrame(false)
, fDisplayStats(false)
, fRefresh(false)
, fShowImGuiDebugWindow(false)
fBackendType = get_backend_type(FLAGS_backend[0]);
fWindow = Window::CreateNativeWindow(platformData);
- fWindow->attach(fBackendType, DisplayParams());
// register callbacks
fCommands.attach(fWindow);
+ fWindow->registerBackendCreatedFunc(on_backend_created_func, this);
fWindow->registerPaintFunc(on_paint_handler, this);
fWindow->registerTouchFunc(on_touch_handler, this);
fWindow->registerUIStateChangedFunc(on_ui_state_changed_handler, this);
}
#endif
fWindow->attach(fBackendType, DisplayParams());
-
- this->updateTitle();
- fWindow->inval();
- fWindow->show();
});
// set up slides
fImGuiGamutPaint.setColor(SK_ColorWHITE);
fImGuiGamutPaint.setFilterQuality(kLow_SkFilterQuality);
- fWindow->show();
+ fWindow->attach(fBackendType, DisplayParams());
}
void Viewer::initSlides() {
if (fCurrentSlide == previousSlide) {
return; // no change; do nothing
}
-
// prepare dimensions for image slides
fSlides[fCurrentSlide]->load(SkIntToScalar(fWindow->width()), SkIntToScalar(fWindow->height()));
}
}
-void Viewer::onPaint(SkCanvas* canvas) {
- // We have to wait until the first draw to make sure the window size is set correctly
- if (!fSetupFirstFrame) {
- // set up first frame
- setupCurrentSlide(-1);
- fSetupFirstFrame = true;
- }
+void Viewer::onBackendCreated() {
+ this->updateTitle();
+ this->updateUIState();
+ this->setupCurrentSlide(-1);
+ fWindow->show();
+ fWindow->inval();
+}
+void Viewer::onPaint(SkCanvas* canvas) {
// Update ImGui input
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = 1.0f / 60.0f;
fBackendType = (sk_app::Window::BackendType)i;
fWindow->detach();
fWindow->attach(fBackendType, DisplayParams());
- fWindow->inval();
- updateTitle();
- updateUIState();
}
break;
}
Viewer(int argc, char** argv, void* platformData);
~Viewer() override;
+ void onBackendCreated();
void onPaint(SkCanvas* canvas);
void onIdle() override;
bool onTouch(intptr_t owner, sk_app::Window::InputState state, float x, float y);
SkAnimTimer fAnimTimer;
SkTArray<sk_sp<Slide>> fSlides;
int fCurrentSlide;
- bool fSetupFirstFrame;
bool fDisplayStats;
bool fRefresh; // whether to continuously refresh for measuring render time
fWindowContext = nullptr;
}
+void Window::onBackendCreated() {
+ fBackendCreatedFunc(fBackendCreatedUserData);
+}
+
bool Window::onChar(SkUnichar c, uint32_t modifiers) {
return fCharFunc(c, modifiers, fCharUserData);
}
}
void Window::onPaint() {
+ if (!fWindowContext) {
+ return;
+ }
markInvalProcessed();
sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface();
if (backbuffer) {
}
void Window::onResize(int w, int h) {
- fWidth = w;
- fHeight = h;
+ if (!fWindowContext) {
+ return;
+ }
fWindowContext->resize(w, h);
}
+int Window::width() {
+ if (!fWindowContext) {
+ return 0;
+ }
+ return fWindowContext->width();
+}
+
+int Window::height() {
+ if (!fWindowContext) {
+ return 0;
+ }
+ return fWindowContext->height();
+}
+
const DisplayParams& Window::getDisplayParams() {
return fWindowContext->getDisplayParams();
}
}
void Window::inval() {
+ if (!fWindowContext) {
+ return;
+ }
if (!fIsContentInvalidated) {
fIsContentInvalidated = true;
onInval();
};
// return value of 'true' means 'I have handled this event'
+ typedef void(*OnBackendCreatedFunc)(void* userData);
typedef bool(*OnCharFunc)(SkUnichar c, uint32_t modifiers, void* userData);
typedef bool(*OnKeyFunc)(Key key, InputState state, uint32_t modifiers, void* userData);
typedef bool(*OnMouseFunc)(int x, int y, InputState state, uint32_t modifiers, void* userData);
const SkString& stateName, const SkString& stateValue, void* userData);
typedef void(*OnPaintFunc)(SkCanvas*, void* userData);
+ void registerBackendCreatedFunc(OnBackendCreatedFunc func, void* userData) {
+ fBackendCreatedFunc = func;
+ fBackendCreatedUserData = userData;
+ }
+
void registerCharFunc(OnCharFunc func, void* userData) {
fCharFunc = func;
fCharUserData = userData;
fUIStateChangedUserData = userData;
}
+ void onBackendCreated();
bool onChar(SkUnichar c, uint32_t modifiers);
bool onKey(Key key, InputState state, uint32_t modifiers);
bool onMouse(int x, int y, InputState state, uint32_t modifiers);
void onPaint();
void onResize(int width, int height);
- int width() { return fWidth; }
- int height() { return fHeight; }
+ int width();
+ int height();
virtual const DisplayParams& getDisplayParams();
void setDisplayParams(const DisplayParams& params);
protected:
Window();
- int fWidth;
- int fHeight;
-
- OnCharFunc fCharFunc;
- void* fCharUserData;
- OnKeyFunc fKeyFunc;
- void* fKeyUserData;
- OnMouseFunc fMouseFunc;
- void* fMouseUserData;
- OnMouseWheelFunc fMouseWheelFunc;
- void* fMouseWheelUserData;
- OnTouchFunc fTouchFunc;
- void* fTouchUserData;
- OnUIStateChangedFunc
- fUIStateChangedFunc;
- void* fUIStateChangedUserData;
- OnPaintFunc fPaintFunc;
- void* fPaintUserData;
+ OnBackendCreatedFunc fBackendCreatedFunc;
+ void* fBackendCreatedUserData;
+ OnCharFunc fCharFunc;
+ void* fCharUserData;
+ OnKeyFunc fKeyFunc;
+ void* fKeyUserData;
+ OnMouseFunc fMouseFunc;
+ void* fMouseUserData;
+ OnMouseWheelFunc fMouseWheelFunc;
+ void* fMouseWheelUserData;
+ OnTouchFunc fTouchFunc;
+ void* fTouchUserData;
+ OnUIStateChangedFunc fUIStateChangedFunc;
+ void* fUIStateChangedUserData;
+ OnPaintFunc fPaintFunc;
+ void* fPaintUserData;
WindowContext* fWindowContext = nullptr;
virtual GrBackendContext getBackendContext() = 0;
GrContext* getGrContext() const { return fContext; }
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+
protected:
virtual bool isGpuContext() { return true; }
break;
#endif
}
+ this->onBackendCreated();
}
void Window_android::onDisplayDestroyed() {
return true;
}
- fWidth = 1280;
- fHeight = 960;
+ constexpr int initialWidth = 1280;
+ constexpr int initialHeight = 960;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- fWidth, fHeight, windowFlags);
+ initialWidth, initialHeight, windowFlags);
if (!fWindow) {
return false;
fWindowContext = NewGLForMac(info, params);
break;
}
+ this->onBackendCreated();
return (SkToBool(fWindowContext));
}
, fWindow(winInfo.fWindow)
, fVisualInfo(winInfo.fVisualInfo)
, fGLContext() {
+ fWidth = winInfo.fWidth;
+ fHeight = winInfo.fHeight;
this->initializeContext();
}
class RasterWindowContext_xlib : public RasterWindowContext {
public:
- RasterWindowContext_xlib(Display*, XWindow, const DisplayParams&);
+ RasterWindowContext_xlib(Display*, XWindow, int width, int height, const DisplayParams&);
sk_sp<SkSurface> getBackbufferSurface() override;
void swapBuffers() override;
GC fGC;
};
-RasterWindowContext_xlib::RasterWindowContext_xlib(Display* display, XWindow window,
- const DisplayParams& params)
+RasterWindowContext_xlib::RasterWindowContext_xlib(Display* display, XWindow window, int width,
+ int height, const DisplayParams& params)
: fDisplay(display)
, fWindow(window) {
fDisplayParams = params;
- XWindowAttributes attrs;
- XGetWindowAttributes(fDisplay, fWindow, &attrs);
fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
- this->resize(attrs.width, attrs.height);
+ this->resize(width, height);
}
void RasterWindowContext_xlib::setDisplayParams(const DisplayParams& params) {
namespace window_context_factory {
WindowContext* NewRasterForXlib(const XlibWindowInfo& info, const DisplayParams& params) {
- WindowContext* ctx = new RasterWindowContext_xlib(info.fDisplay, info.fWindow, params);
+ WindowContext* ctx = new RasterWindowContext_xlib(info.fDisplay, info.fWindow, info.fWidth,
+ info.fHeight, params);
if (!ctx->isValid()) {
delete ctx;
ctx = nullptr;
Display* fDisplay;
XWindow fWindow;
XVisualInfo* fVisualInfo;
+ int fWidth;
+ int fHeight;
};
WindowContext* NewVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
}
fDisplay = display;
- fWidth = 1280;
- fHeight = 960;
+ constexpr int initialWidth = 1280;
+ constexpr int initialHeight = 960;
// Attempt to create a window that supports GL
GLint att[] = {
fWindow = XCreateWindow(display,
RootWindow(display, fVisualInfo->screen),
0, 0, // x, y
- fWidth, fHeight,
+ initialWidth, initialHeight,
0, // border width
fVisualInfo->depth,
InputOutput,
fWindow = XCreateSimpleWindow(display,
DefaultRootWindow(display),
0, 0, // x, y
- fWidth, fHeight,
+ initialWidth, initialHeight,
0, // border width
0, // border value
0); // background value
winInfo.fDisplay = fDisplay;
winInfo.fWindow = fWindow;
winInfo.fVisualInfo = fVisualInfo;
+
+ XWindowAttributes attrs;
+ if (XGetWindowAttributes(fDisplay, fWindow, &attrs)) {
+ winInfo.fWidth = attrs.width;
+ winInfo.fHeight = attrs.height;
+ } else {
+ winInfo.fWidth = winInfo.fHeight = 0;
+ }
+
switch (attachType) {
#ifdef SK_VULKAN
case kVulkan_BackendType:
fWindowContext = window_context_factory::NewRasterForXlib(winInfo, params);
break;
}
+ this->onBackendCreated();
return (SkToBool(fWindowContext));
}
event.xexpose.window = fWindow;
event.xexpose.x = 0;
event.xexpose.y = 0;
- event.xexpose.width = fWidth;
- event.xexpose.height = fHeight;
+ event.xexpose.width = this->width();
+ event.xexpose.height = this->height();
event.xexpose.count = 0;
XSendEvent(fDisplay, fWindow, False, 0, &event);
}
void markPendingResize(int width, int height) {
- if (width != fWidth || height != fHeight){
+ if (width != this->width() || height != this->height()){
fPendingResize = true;
fPendingWidth = width;
fPendingHeight = height;
break;
#endif
}
+ this->onBackendCreated();
return (SkToBool(fWindowContext));
}