Add msaa flag and UI to viewer

BUG=skia:

Change-Id: I0a24d5e6a4271f84ea5c82eb6d9ede9a1e63f86a
Reviewed-on: https://skia-review.googlesource.com/8787
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
csmartdalton 2017-02-24 16:04:47 -07:00 committed by Skia Commit-Bot
parent ab8e02a4de
commit 578f064a60
17 changed files with 170 additions and 81 deletions

View File

@ -33,6 +33,8 @@
#include "imgui.h"
#include <stdlib.h>
using namespace sk_app;
Application* Application::Create(int argc, char** argv, void* platformData) {
@ -142,14 +144,15 @@ static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BA
static DEFINE_bool(atrace, false, "Enable support for using ATrace. ATrace is only supported on Android.");
DEFINE_int32(msaa, 0, "Number of subpixel samples. 0 for no HW antialiasing.");
DEFINE_pathrenderer_flag;
const char *kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = {
" [OpenGL]",
"OpenGL",
#ifdef SK_VULKAN
" [Vulkan]",
"Vulkan",
#endif
" [Raster]"
"Raster"
};
static sk_app::Window::BackendType get_backend_type(const char* str) {
@ -211,6 +214,7 @@ const char* kValue = "value";
const char* kOptions = "options";
const char* kSlideStateName = "Slide";
const char* kBackendStateName = "Backend";
const char* kMSAAStateName = "MSAA";
const char* kSoftkeyStateName = "Softkey";
const char* kSoftkeyHint = "Please select a softkey";
const char* kFpsStateName = "FPS";
@ -259,6 +263,10 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
fBackendType = get_backend_type(FLAGS_backend[0]);
fWindow = Window::CreateNativeWindow(platformData);
DisplayParams displayParams;
displayParams.fMSAASampleCount = FLAGS_msaa;
fWindow->setRequestedDisplayParams(displayParams);
// register callbacks
fCommands.attach(fWindow);
fWindow->registerBackendCreatedFunc(on_backend_created_func, this);
@ -362,7 +370,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
fWindow->registerCharFunc(on_char_handler, this);
}
#endif
fWindow->attach(fBackendType, DisplayParams());
fWindow->attach(fBackendType);
});
// set up slides
@ -423,7 +431,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
fImGuiGamutPaint.setColor(SK_ColorWHITE);
fImGuiGamutPaint.setFilterQuality(kLow_SkFilterQuality);
fWindow->attach(fBackendType, DisplayParams());
fWindow->attach(fBackendType);
}
void Viewer::initSlides() {
@ -512,6 +520,13 @@ Viewer::~Viewer() {
}
void Viewer::updateTitle() {
if (!fWindow) {
return;
}
if (fWindow->sampleCount() < 0) {
return; // Surface hasn't been created yet.
}
SkString title("Viewer: ");
title.append(fSlides[fCurrentSlide]->getName());
@ -530,7 +545,12 @@ void Viewer::updateTitle() {
title.appendf(" %s", curPrimaries >= 0 ? gNamedPrimaries[curPrimaries].fName : "Custom");
}
title.append(" [");
title.append(kBackendTypeStrings[fBackendType]);
if (int msaa = fWindow->sampleCount()) {
title.appendf(" MSAA: %i", msaa);
}
title.append("]");
fWindow->setTitle(title.c_str());
}
@ -642,10 +662,10 @@ void Viewer::setColorMode(SkColorType colorType, bool colorManaged) {
// When we're in color managed mode, we tag our window surface as sRGB. If we've switched into
// or out of legacy mode, we need to update our window configuration.
DisplayParams params = fWindow->getDisplayParams();
DisplayParams params = fWindow->getRequestedDisplayParams();
if (fColorManaged != SkToBool(params.fColorSpace)) {
params.fColorSpace = fColorManaged ? SkColorSpace::MakeSRGB() : nullptr;
fWindow->setDisplayParams(params);
fWindow->setRequestedDisplayParams(params);
}
this->updateTitle();
@ -1060,6 +1080,13 @@ void Viewer::onIdle() {
}
void Viewer::updateUIState() {
if (!fWindow) {
return;
}
if (fWindow->sampleCount() < 0) {
return; // Surface hasn't been created yet.
}
// Slide state
Json::Value slideState(Json::objectValue);
slideState[kName] = kSlideStateName;
@ -1080,6 +1107,19 @@ void Viewer::updateUIState() {
backendState[kOptions].append(Json::Value(str));
}
// MSAA state
Json::Value msaaState(Json::objectValue);
msaaState[kName] = kMSAAStateName;
msaaState[kValue] = fWindow->sampleCount();
msaaState[kOptions] = Json::Value(Json::arrayValue);
if (sk_app::Window::kRaster_BackendType == fBackendType) {
msaaState[kOptions].append(Json::Value(0));
} else {
for (int msaa : {0, 4, 8, 16}) {
msaaState[kOptions].append(Json::Value(msaa));
}
}
// Softkey state
Json::Value softkeyState(Json::objectValue);
softkeyState[kName] = kSoftkeyStateName;
@ -1104,6 +1144,7 @@ void Viewer::updateUIState() {
Json::Value state(Json::arrayValue);
state.append(slideState);
state.append(backendState);
state.append(msaaState);
state.append(softkeyState);
state.append(fpsState);
@ -1135,11 +1176,20 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
if (fBackendType != i) {
fBackendType = (sk_app::Window::BackendType)i;
fWindow->detach();
fWindow->attach(fBackendType, DisplayParams());
fWindow->attach(fBackendType);
}
break;
}
}
} else if (stateName.equals(kMSAAStateName)) {
DisplayParams params = fWindow->getRequestedDisplayParams();
int sampleCount = atoi(stateValue.c_str());
if (sampleCount != params.fMSAASampleCount) {
params.fMSAASampleCount = sampleCount;
fWindow->setRequestedDisplayParams(params);
fWindow->inval();
updateTitle();
}
} else if (stateName.equals(kSoftkeyStateName)) {
if (!stateValue.equals(kSoftkeyHint)) {
fCommands.onSoftkey(stateValue);

View File

@ -19,6 +19,7 @@
#include "SkCanvas.h"
#include "SkImage_Base.h"
#include "SkMathPriv.h"
namespace sk_app {
@ -27,6 +28,9 @@ GLWindowContext::GLWindowContext(const DisplayParams& params)
, fBackendContext(nullptr)
, fSurface(nullptr) {
fDisplayParams = params;
fDisplayParams.fMSAASampleCount = fDisplayParams.fMSAASampleCount ?
GrNextPow2(fDisplayParams.fMSAASampleCount) :
0;
}
void GLWindowContext::initializeContext() {
@ -38,11 +42,20 @@ void GLWindowContext::initializeContext() {
fBackendContext.reset(GrGLCreateNativeInterface());
fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fBackendContext.get(),
ctxOptions);
if (!fContext && fDisplayParams.fMSAASampleCount) {
fDisplayParams.fMSAASampleCount /= 2;
this->initializeContext();
return;
}
// We may not have real sRGB support (ANGLE, in particular), so check for
// that, and fall back to L32:
fPixelConfig = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace
? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
if (fContext) {
// We may not have real sRGB support (ANGLE, in particular), so check for
// that, and fall back to L32:
fPixelConfig = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace
? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
} else {
fPixelConfig = kUnknown_GrPixelConfig;
}
}
void GLWindowContext::destroyContext() {

View File

@ -52,12 +52,6 @@ protected:
sk_sp<const GrGLInterface> fBackendContext;
sk_sp<SkSurface> fSurface;
// parameters obtained from the native window
// Note that the platform .cpp file is responsible for
// initializing fSampleCount and fStencilBits!
int fSampleCount;
int fStencilBits;
};
} // namespace sk_app

View File

@ -187,6 +187,8 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
}
}
fDisplayParams = params;
fSampleCount = params.fMSAASampleCount;
fStencilBits = 8;
if (VK_FORMAT_UNDEFINED == surfaceFormat) {
return false;
@ -276,8 +278,8 @@ void VulkanWindowContext::createBuffers(VkFormat format) {
desc.fHeight = fHeight;
desc.fConfig = fPixelConfig;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fSampleCnt = 0;
desc.fStencilBits = 0;
desc.fSampleCnt = fSampleCount;
desc.fStencilBits = fStencilBits;
desc.fRenderTargetHandle = (GrBackendObject) &info;
fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc,

View File

@ -125,12 +125,25 @@ int Window::height() {
return fWindowContext->height();
}
const DisplayParams& Window::getDisplayParams() {
return fWindowContext->getDisplayParams();
void Window::setRequestedDisplayParams(const DisplayParams& params) {
fRequestedDisplayParams = params;
if (fWindowContext) {
fWindowContext->setDisplayParams(fRequestedDisplayParams);
}
}
void Window::setDisplayParams(const DisplayParams& params) {
fWindowContext->setDisplayParams(params);
int Window::sampleCount() const {
if (!fWindowContext) {
return -1;
}
return fWindowContext->sampleCount();
}
int Window::stencilBits() const {
if (!fWindowContext) {
return -1;
}
return fWindowContext->stencilBits();
}
void Window::inval() {

View File

@ -53,7 +53,7 @@ public:
kBackendTypeCount = kLast_BackendType + 1
};
virtual bool attach(BackendType attachType, const DisplayParams& params) = 0;
virtual bool attach(BackendType) = 0;
void detach();
// input handling
@ -191,8 +191,12 @@ public:
int width();
int height();
virtual const DisplayParams& getDisplayParams();
void setDisplayParams(const DisplayParams& params);
virtual const DisplayParams& getRequestedDisplayParams() { return fRequestedDisplayParams; }
void setRequestedDisplayParams(const DisplayParams&);
// Actual parameters in effect, obtained from the native window.
int sampleCount() const;
int stencilBits() const;
protected:
Window();
@ -213,6 +217,7 @@ protected:
void* fUIStateChangedUserData;
OnPaintFunc fPaintFunc;
void* fPaintUserData;
DisplayParams fRequestedDisplayParams;
WindowContext* fWindowContext = nullptr;

View File

@ -21,7 +21,9 @@ namespace sk_app {
class WindowContext {
public:
WindowContext() : fContext(nullptr)
, fSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType) {}
, fSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)
, fSampleCount(0)
, fStencilBits(0) {}
virtual ~WindowContext() {}
@ -46,6 +48,8 @@ public:
int width() const { return fWidth; }
int height() const { return fHeight; }
int sampleCount() const { return fSampleCount; }
int stencilBits() const { return fStencilBits; }
protected:
virtual bool isGpuContext() { return true; }
@ -57,6 +61,12 @@ protected:
DisplayParams fDisplayParams;
GrPixelConfig fPixelConfig;
SkSurfaceProps fSurfaceProps;
// parameters obtained from the native window
// Note that the platform .cpp file is responsible for
// initializing fSampleCount and fStencilBits!
int fSampleCount;
int fStencilBits;
};
} // namespace sk_app

View File

@ -74,6 +74,9 @@ void GLWindowContext_android::onInitializeContext() {
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_STENCIL_SIZE, 8,
EGL_SAMPLE_BUFFERS, fDisplayParams.fMSAASampleCount ? 1 : 0,
EGL_SAMPLES, fDisplayParams.fMSAASampleCount,
EGL_NONE
};

View File

@ -27,16 +27,6 @@ bool Window_android::init(SkiaAndroidApp* skiaAndroidApp) {
return true;
}
const DisplayParams& Window_android::getDisplayParams() {
if (fWindowContext) {
return fWindowContext->getDisplayParams();
} else {
// fWindowContext doesn't exist because we haven't
// initDisplay yet.
return fDisplayParams;
}
}
void Window_android::setTitle(const char* title) {
fSkiaAndroidApp->setTitle(title);
}
@ -45,9 +35,8 @@ void Window_android::setUIState(const Json::Value& state) {
fSkiaAndroidApp->setUIState(state);
}
bool Window_android::attach(BackendType attachType, const DisplayParams& params) {
bool Window_android::attach(BackendType attachType) {
fBackendType = attachType;
fDisplayParams = params;
// We delay the creation of fWindowContext until Android informs us that
// the native window is ready to use.
@ -60,14 +49,17 @@ void Window_android::initDisplay(ANativeWindow* window) {
switch (fBackendType) {
case kNativeGL_BackendType:
default:
fWindowContext = window_context_factory::NewGLForAndroid(window, fDisplayParams);
fWindowContext = window_context_factory::NewGLForAndroid(window,
fRequestedDisplayParams);
break;
case kRaster_BackendType:
fWindowContext = window_context_factory::NewRasterForAndroid(window, fDisplayParams);
fWindowContext = window_context_factory::NewRasterForAndroid(window,
fRequestedDisplayParams);
break;
#ifdef SK_VULKAN
case kVulkan_BackendType:
fWindowContext = window_context_factory::NewVulkanForAndroid(window, fDisplayParams);
fWindowContext = window_context_factory::NewVulkanForAndroid(window,
fRequestedDisplayParams);
break;
#endif
}

View File

@ -22,11 +22,10 @@ public:
void initDisplay(ANativeWindow* window);
void onDisplayDestroyed();
const DisplayParams& getDisplayParams() override;
void setTitle(const char*) override;
void show() override {}
bool attach(BackendType attachType, const DisplayParams& params) override;
bool attach(BackendType) override;
void onInval() override;
void setUIState(const Json::Value& state) override;
@ -40,7 +39,6 @@ public:
private:
SkiaAndroidApp* fSkiaAndroidApp = nullptr;
SkRect fContentRect;
DisplayParams fDisplayParams;
BackendType fBackendType;
};

View File

@ -16,7 +16,7 @@ SkTDynamicHash<Window_mac, Uint32> Window_mac::gWindowMap;
Window* Window::CreateNativeWindow(void*) {
Window_mac* window = new Window_mac();
if (!window->initWindow(nullptr)) {
if (!window->initWindow()) {
delete window;
return nullptr;
}
@ -24,8 +24,8 @@ Window* Window::CreateNativeWindow(void*) {
return window;
}
bool Window_mac::initWindow(const DisplayParams* params) {
if (params && params->fMSAASampleCount != fMSAASampleCount) {
bool Window_mac::initWindow() {
if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
this->closeWindow();
}
// we already have a window
@ -49,9 +49,9 @@ bool Window_mac::initWindow(const DisplayParams* params) {
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
if (params && params->fMSAASampleCount > 0) {
if (fRequestedDisplayParams.fMSAASampleCount > 0) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, params->fMSAASampleCount);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fRequestedDisplayParams.fMSAASampleCount);
} else {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
}
@ -65,6 +65,8 @@ bool Window_mac::initWindow(const DisplayParams* params) {
return false;
}
fMSAASampleCount = fRequestedDisplayParams.fMSAASampleCount;
// add to hashtable of windows
fWindowID = SDL_GetWindowID(fWindow);
gWindowMap.add(this);
@ -244,19 +246,19 @@ void Window_mac::show() {
SDL_ShowWindow(fWindow);
}
bool Window_mac::attach(BackendType attachType, const DisplayParams& params) {
this->initWindow(&params);
bool Window_mac::attach(BackendType attachType) {
this->initWindow();
window_context_factory::MacWindowInfo info;
info.fWindow = fWindow;
switch (attachType) {
case kRaster_BackendType:
fWindowContext = NewRasterForMac(info, params);
fWindowContext = NewRasterForMac(info, fRequestedDisplayParams);
break;
case kNativeGL_BackendType:
default:
fWindowContext = NewGLForMac(info, params);
fWindowContext = NewGLForMac(info, fRequestedDisplayParams);
break;
}
this->onBackendCreated();

View File

@ -25,12 +25,12 @@ public:
, fMSAASampleCount(0) {}
~Window_mac() override { this->closeWindow(); }
bool initWindow(const DisplayParams* params);
bool initWindow();
void setTitle(const char*) override;
void show() override;
bool attach(BackendType attachType, const DisplayParams& params) override;
bool attach(BackendType) override;
void onInval() override;

View File

@ -29,7 +29,7 @@ Window* Window::CreateNativeWindow(void* platformData) {
SkASSERT(display);
Window_unix* window = new Window_unix();
if (!window->initWindow(display, nullptr)) {
if (!window->initWindow(display)) {
delete window;
return nullptr;
}
@ -41,8 +41,8 @@ const long kEventMask = ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
if (params && params->fMSAASampleCount != fMSAASampleCount) {
bool Window_unix::initWindow(Display* display) {
if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
this->closeWindow();
}
// we already have a window
@ -63,7 +63,7 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
None
};
SkASSERT(nullptr == fVisualInfo);
if (params && params->fMSAASampleCount > 0) {
if (fRequestedDisplayParams.fMSAASampleCount > 0) {
static const GLint kAttCount = SK_ARRAY_COUNT(att);
GLint msaaAtt[kAttCount + 4];
memcpy(msaaAtt, att, sizeof(att));
@ -71,14 +71,12 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
msaaAtt[kAttCount + 0] = 1;
msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
msaaAtt[kAttCount + 2] = params->fMSAASampleCount;
msaaAtt[kAttCount + 2] = fRequestedDisplayParams.fMSAASampleCount;
msaaAtt[kAttCount + 3] = None;
fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt);
fMSAASampleCount = params->fMSAASampleCount;
}
if (nullptr == fVisualInfo) {
fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att);
fMSAASampleCount = 0;
}
if (fVisualInfo) {
@ -115,6 +113,8 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
return false;
}
fMSAASampleCount = fRequestedDisplayParams.fMSAASampleCount;
// set up to catch window delete message
fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);
@ -132,15 +132,15 @@ bool Window_unix::initWindow(Display* display, const DisplayParams* params) {
void Window_unix::closeWindow() {
if (fDisplay) {
this->detach();
SkASSERT(fGC);
XFreeGC(fDisplay, fGC);
fGC = nullptr;
if (fGC) {
XFreeGC(fDisplay, fGC);
fGC = nullptr;
}
gWindowMap.remove(fWindow);
XDestroyWindow(fDisplay, fWindow);
fWindow = 0;
fVisualInfo = nullptr;
fDisplay = nullptr;
fMSAASampleCount = 0;
}
}
@ -292,8 +292,8 @@ void Window_unix::show() {
XMapWindow(fDisplay, fWindow);
}
bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
this->initWindow(fDisplay, &params);
bool Window_unix::attach(BackendType attachType) {
this->initWindow(fDisplay);
window_context_factory::XlibWindowInfo winInfo;
winInfo.fDisplay = fDisplay;
@ -311,14 +311,16 @@ bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
switch (attachType) {
#ifdef SK_VULKAN
case kVulkan_BackendType:
fWindowContext = window_context_factory::NewVulkanForXlib(winInfo, params);
fWindowContext = window_context_factory::NewVulkanForXlib(winInfo,
fRequestedDisplayParams);
break;
#endif
case kNativeGL_BackendType:
fWindowContext = window_context_factory::NewGLForXlib(winInfo, params);
fWindowContext = window_context_factory::NewGLForXlib(winInfo, fRequestedDisplayParams);
break;
case kRaster_BackendType:
fWindowContext = window_context_factory::NewRasterForXlib(winInfo, params);
fWindowContext = window_context_factory::NewRasterForXlib(winInfo,
fRequestedDisplayParams);
break;
}
this->onBackendCreated();

View File

@ -28,12 +28,12 @@ public:
, fMSAASampleCount(0) {}
~Window_unix() override { this->closeWindow(); }
bool initWindow(Display* display, const DisplayParams* params);
bool initWindow(Display* display);
void setTitle(const char*) override;
void show() override;
bool attach(BackendType attachType, const DisplayParams& params) override;
bool attach(BackendType) override;
void onInval() override;

View File

@ -1,4 +1,5 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
@ -53,7 +54,9 @@ int main(int argc, char**argv) {
XNextEvent(display, &event);
sk_app::Window_unix* win = sk_app::Window_unix::gWindowMap.find(event.xany.window);
SkASSERT(win);
if (!win) {
continue;
}
// paint and resize events get collapsed
switch (event.type) {

View File

@ -290,17 +290,19 @@ void Window_win::show() {
}
bool Window_win::attach(BackendType attachType, const DisplayParams& params) {
bool Window_win::attach(BackendType attachType) {
switch (attachType) {
case kNativeGL_BackendType:
fWindowContext = window_context_factory::NewGLForWin(fHWnd, params);
fWindowContext = window_context_factory::NewGLForWin(fHWnd, fRequestedDisplayParams);
break;
case kRaster_BackendType:
fWindowContext = window_context_factory::NewRasterForWin(fHWnd, params);
fWindowContext = window_context_factory::NewRasterForWin(fHWnd,
fRequestedDisplayParams);
break;
#ifdef SK_VULKAN
case kVulkan_BackendType:
fWindowContext = window_context_factory::NewVulkanForWin(fHWnd, params);
fWindowContext = window_context_factory::NewVulkanForWin(fHWnd,
fRequestedDisplayParams);
break;
#endif
}

View File

@ -23,7 +23,7 @@ public:
void setTitle(const char*) override;
void show() override;
bool attach(BackendType attachType, const DisplayParams& params) override;
bool attach(BackendType) override;
void onInval() override;