Add onBackendCreated callback to Viewer
authorChristopher Dalton <csmartdalton@google.com>
Fri, 24 Feb 2017 20:22:53 +0000 (13:22 -0700)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 24 Feb 2017 22:37:34 +0000 (22:37 +0000)
Also removes fWidth and fHeight from Window and instead
calls into WindowContent to get these values.

BUG=skia:

Change-Id: I72ee506004b7da73db9abb607a3bc82edfcf7d43
Reviewed-on: https://skia-review.googlesource.com/8795
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Yuqian Li <liyuqian@google.com>
16 files changed:
tools/viewer/ImageSlide.cpp
tools/viewer/SampleSlide.cpp
tools/viewer/SampleSlide.h
tools/viewer/Viewer.cpp
tools/viewer/Viewer.h
tools/viewer/sk_app/Window.cpp
tools/viewer/sk_app/Window.h
tools/viewer/sk_app/WindowContext.h
tools/viewer/sk_app/android/Window_android.cpp
tools/viewer/sk_app/mac/Window_mac.cpp
tools/viewer/sk_app/unix/GLWindowContext_unix.cpp
tools/viewer/sk_app/unix/RasterWindowContext_unix.cpp
tools/viewer/sk_app/unix/WindowContextFactory_unix.h
tools/viewer/sk_app/unix/Window_unix.cpp
tools/viewer/sk_app/unix/Window_unix.h
tools/viewer/sk_app/win/Window_win.cpp

index dd7adba..8ff7d18 100644 (file)
@@ -20,6 +20,7 @@ SkISize ImageSlide::getDimensions() const {
 }
 
 void ImageSlide::draw(SkCanvas* canvas) {
+    SkASSERT(fImage);
     canvas->drawImage(fImage, 0, 0);
 }
 
index 00ee534..93a495e 100644 (file)
@@ -21,22 +21,25 @@ SampleSlide::SampleSlide(const SkViewFactory* factory) : fViewFactory(factory) {
 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);
index ab45c01..24325c9 100644 (file)
@@ -20,8 +20,8 @@ public:
     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;
     }
@@ -30,7 +30,7 @@ public:
 
 private:
     const SkViewFactory*   fViewFactory;
-    SkView*                fView;
+    sk_sp<SkView>          fView;
 };
 
 #endif
index e056b43..0949900 100644 (file)
@@ -39,6 +39,12 @@ Application* Application::Create(int argc, char** argv, void* platformData) {
     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);
 
@@ -214,7 +220,6 @@ const char* kRefreshStateName = "Refresh";
 
 Viewer::Viewer(int argc, char** argv, void* platformData)
     : fCurrentMeasurement(0)
-    , fSetupFirstFrame(false)
     , fDisplayStats(false)
     , fRefresh(false)
     , fShowImGuiDebugWindow(false)
@@ -253,10 +258,10 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
 
     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);
@@ -358,10 +363,6 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
         }
 #endif
         fWindow->attach(fBackendType, DisplayParams());
-
-        this->updateTitle();
-        fWindow->inval();
-        fWindow->show();
     });
 
     // set up slides
@@ -422,7 +423,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
     fImGuiGamutPaint.setColor(SK_ColorWHITE);
     fImGuiGamutPaint.setFilterQuality(kLow_SkFilterQuality);
 
-    fWindow->show();
+    fWindow->attach(fBackendType, DisplayParams());
 }
 
 void Viewer::initSlides() {
@@ -563,7 +564,6 @@ void Viewer::setupCurrentSlide(int previousSlide) {
     if (fCurrentSlide == previousSlide) {
         return; // no change; do nothing
     }
-
     // prepare dimensions for image slides
     fSlides[fCurrentSlide]->load(SkIntToScalar(fWindow->width()), SkIntToScalar(fWindow->height()));
 
@@ -712,14 +712,15 @@ void Viewer::drawSlide(SkCanvas* canvas) {
     }
 }
 
-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;
@@ -1135,9 +1136,6 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
                     fBackendType = (sk_app::Window::BackendType)i;
                     fWindow->detach();
                     fWindow->attach(fBackendType, DisplayParams());
-                    fWindow->inval();
-                    updateTitle();
-                    updateUIState();
                 }
                 break;
             }
index 1364592..9cc08a3 100644 (file)
@@ -23,6 +23,7 @@ public:
     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);
@@ -58,7 +59,6 @@ private:
     SkAnimTimer            fAnimTimer;
     SkTArray<sk_sp<Slide>> fSlides;
     int                    fCurrentSlide;
-    bool                   fSetupFirstFrame;
 
     bool                   fDisplayStats;
     bool                   fRefresh; // whether to continuously refresh for measuring render time
index 9d14a17..5a9d824 100644 (file)
@@ -55,6 +55,10 @@ void Window::detach() {
     fWindowContext = nullptr;
 }
 
+void Window::onBackendCreated() {
+    fBackendCreatedFunc(fBackendCreatedUserData);
+}
+
 bool Window::onChar(SkUnichar c, uint32_t modifiers) {
     return fCharFunc(c, modifiers, fCharUserData);
 }
@@ -80,6 +84,9 @@ void Window::onUIStateChanged(const SkString& stateName, const SkString& stateVa
 }
 
 void Window::onPaint() {
+    if (!fWindowContext) {
+        return;
+    }
     markInvalProcessed();
     sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface();
     if (backbuffer) {
@@ -98,11 +105,26 @@ void Window::onPaint() {
 }
 
 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();
 }
@@ -112,6 +134,9 @@ void Window::setDisplayParams(const DisplayParams& params) {
 }
 
 void Window::inval() {
+    if (!fWindowContext) {
+        return;
+    }
     if (!fIsContentInvalidated) {
         fIsContentInvalidated = true;
         onInval();
index b20eec8..24919a8 100644 (file)
@@ -128,6 +128,7 @@ public:
     };
 
     // 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);
@@ -137,6 +138,11 @@ public:
             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;
@@ -172,6 +178,7 @@ public:
         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);
@@ -181,8 +188,8 @@ public:
     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);
@@ -190,24 +197,22 @@ public:
 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;
 
index 75edf2d..ff5dd63 100644 (file)
@@ -44,6 +44,9 @@ public:
     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;  }
 
index 86f20be..11a1f04 100644 (file)
@@ -71,6 +71,7 @@ void Window_android::initDisplay(ANativeWindow* window) {
             break;
 #endif
     }
+    this->onBackendCreated();
 }
 
 void Window_android::onDisplayDestroyed() {
index a23316d..bf5e01f 100644 (file)
@@ -33,8 +33,8 @@ bool Window_mac::initWindow(const DisplayParams* params) {
         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);
@@ -59,7 +59,7 @@ bool Window_mac::initWindow(const DisplayParams* params) {
 
     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;
@@ -259,6 +259,7 @@ bool Window_mac::attach(BackendType attachType, const DisplayParams& params) {
             fWindowContext = NewGLForMac(info, params);
             break;
     }
+    this->onBackendCreated();
 
     return (SkToBool(fWindowContext));
 }
index ead7037..a46bb62 100644 (file)
@@ -44,6 +44,8 @@ GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const
         , fWindow(winInfo.fWindow)
         , fVisualInfo(winInfo.fVisualInfo)
         , fGLContext() {
+    fWidth = winInfo.fWidth;
+    fHeight = winInfo.fHeight;
     this->initializeContext();
 }
 
index 16b11a9..50aa280 100644 (file)
@@ -16,7 +16,7 @@ namespace {
 
 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;
@@ -31,15 +31,13 @@ protected:
     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) {
@@ -88,7 +86,8 @@ namespace sk_app {
 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;
index b1e21ac..1cc811d 100644 (file)
@@ -24,6 +24,8 @@ struct XlibWindowInfo {
     Display*     fDisplay;
     XWindow      fWindow;
     XVisualInfo* fVisualInfo;
+    int          fWidth;
+    int          fHeight;
 };
 
 WindowContext* NewVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
index 2481bdb..d7bb849 100644 (file)
@@ -51,8 +51,8 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
     }
     fDisplay = display;
 
-    fWidth = 1280;
-    fHeight = 960;
+    constexpr int initialWidth = 1280;
+    constexpr int initialHeight = 960;
 
     // Attempt to create a window that supports GL
     GLint att[] = {
@@ -92,7 +92,7 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
         fWindow = XCreateWindow(display,
                                 RootWindow(display, fVisualInfo->screen),
                                 0, 0, // x, y
-                                fWidth, fHeight,
+                                initialWidth, initialHeight,
                                 0, // border width
                                 fVisualInfo->depth,
                                 InputOutput,
@@ -104,7 +104,7 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
         fWindow = XCreateSimpleWindow(display,
                                       DefaultRootWindow(display),
                                       0, 0,  // x, y
-                                      fWidth, fHeight,
+                                      initialWidth, initialHeight,
                                       0,     // border width
                                       0,     // border value
                                       0);    // background value
@@ -299,6 +299,15 @@ bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
     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:
@@ -312,6 +321,7 @@ bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
             fWindowContext = window_context_factory::NewRasterForXlib(winInfo, params);
             break;
     }
+    this->onBackendCreated();
 
     return (SkToBool(fWindowContext));
 }
@@ -324,8 +334,8 @@ void Window_unix::onInval() {
     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);
index 462214d..b0c06c5 100644 (file)
@@ -58,7 +58,7 @@ public:
     }
 
     void markPendingResize(int width, int height) {
-        if (width != fWidth || height != fHeight){
+        if (width != this->width() || height != this->height()){
             fPendingResize = true;
             fPendingWidth = width;
             fPendingHeight = height;
index 6f6e72d..7fa12a4 100644 (file)
@@ -304,6 +304,7 @@ bool Window_win::attach(BackendType attachType, const DisplayParams& params) {
             break;
 #endif
     }
+    this->onBackendCreated();
 
     return (SkToBool(fWindowContext));
 }