Add MSAA option to SampleApp
Review URL: http://codereview.appspot.com/5969049
git-svn-id: http://skia.googlecode.com/svn/trunk@3627 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/iOSSampleApp/SkSampleUIView.mm b/experimental/iOSSampleApp/SkSampleUIView.mm
index 5ec6146..b1ec537 100644
--- a/experimental/iOSSampleApp/SkSampleUIView.mm
+++ b/experimental/iOSSampleApp/SkSampleUIView.mm
@@ -108,6 +108,10 @@
bool isUsingGL() { return usingGL; }
virtual GrContext* getGrContext() { return fGrContext; }
+
+ virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
+ return fGrRenderTarget;
+ }
private:
bool usingGL;
GrContext* fGrContext;
diff --git a/include/views/SkOSWindow_Android.h b/include/views/SkOSWindow_Android.h
index 5818a0a..9b72b48 100644
--- a/include/views/SkOSWindow_Android.h
+++ b/include/views/SkOSWindow_Android.h
@@ -24,7 +24,9 @@
kNativeGL_BackEndType,
};
- bool attach(SkBackEndTypes /* attachType */) { return true; }
+ bool attach(SkBackEndTypes /* attachType */, int /* msaaSampleCount */) {
+ return true;
+ }
void detach() {}
void present() {}
diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h
index 01fa29f..e3bcea9 100644
--- a/include/views/SkOSWindow_Mac.h
+++ b/include/views/SkOSWindow_Mac.h
@@ -16,19 +16,18 @@
SkOSWindow(void* hwnd);
~SkOSWindow();
void* getHWND() const { return fHWND; }
-
+
virtual bool onDispatchClick(int x, int y, Click::State state,
void* owner);
-
enum SkBackEndTypes {
kNone_BackEndType,
kNativeGL_BackEndType,
};
void detach();
- bool attach(SkBackEndTypes attachType);
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount);
void present();
-
+
protected:
// overrides from SkEventSink
virtual bool onEvent(const SkEvent& evt);
diff --git a/include/views/SkOSWindow_Unix.h b/include/views/SkOSWindow_Unix.h
index 384cc7b..d967579 100644
--- a/include/views/SkOSWindow_Unix.h
+++ b/include/views/SkOSWindow_Unix.h
@@ -39,10 +39,12 @@
kNativeGL_BackEndType,
};
- bool attach(SkBackEndTypes attachType);
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount);
void detach();
void present();
+ int getMSAASampleCount() const { return fMSAASampleCount; }
+
//static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
//static bool WndProc(SkUnixWindow* w, XEvent &e);
@@ -60,10 +62,15 @@
void doPaint();
void mapWindowAndWait();
+ void closeWindow();
+ void initWindow(int newMSAASampleCount);
+
SkUnixWindow fUnixWindow;
// Needed for GL
XVisualInfo* fVi;
+ // we recreate the underlying xwindow if this changes
+ int fMSAASampleCount;
typedef SkWindow INHERITED;
};
diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h
index 9c76d5c..f61c80a 100644
--- a/include/views/SkOSWindow_Win.h
+++ b/include/views/SkOSWindow_Win.h
@@ -35,7 +35,7 @@
#endif
};
- bool attach(SkBackEndTypes attachType);
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount);
void detach();
void present();
@@ -73,12 +73,12 @@
SkBackEndTypes fAttached;
- bool attachGL();
+ bool attachGL(int msaaSampleCount);
void detachGL();
void presentGL();
#if SK_ANGLE
- bool attachANGLE();
+ bool attachANGLE(int msaaSampleCount);
void detachANGLE();
void presentANGLE();
#endif
diff --git a/include/views/SkOSWindow_iOS.h b/include/views/SkOSWindow_iOS.h
index 34ce421..33f014c 100755
--- a/include/views/SkOSWindow_iOS.h
+++ b/include/views/SkOSWindow_iOS.h
@@ -25,7 +25,7 @@
};
void detach();
- bool attach(SkBackEndTypes attachType);
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount);
void present();
protected:
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 92c9e6c..1cd9c67 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -139,7 +139,8 @@
: fCurContext(NULL)
, fCurIntf(NULL)
, fCurRenderTarget(NULL)
- , fBackend(kNone_BackEndType) {
+ , fBackend(kNone_BackEndType)
+ , fMSAASampleCount(0) {
}
virtual ~DefaultDeviceManager() {
@@ -148,7 +149,7 @@
SkSafeUnref(fCurRenderTarget);
}
- virtual void setUpBackend(SampleWindow* win) {
+ virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) {
SkASSERT(kNone_BackEndType == fBackend);
fBackend = kNone_BackEndType;
@@ -175,11 +176,12 @@
break;
}
- bool result = win->attach(fBackend);
+ bool result = win->attach(fBackend, msaaSampleCount);
if (!result) {
SkDebugf("Failed to initialize GL");
return;
}
+ fMSAASampleCount = msaaSampleCount;
SkASSERT(NULL == fCurIntf);
switch (win->getDeviceType()) {
@@ -287,7 +289,7 @@
virtual void windowSizeChanged(SampleWindow* win) {
if (fCurContext) {
- win->attach(fBackend);
+ win->attach(fBackend, fMSAASampleCount);
GrPlatformRenderTargetDesc desc;
desc.fWidth = SkScalarRound(win->width());
@@ -307,12 +309,18 @@
virtual GrContext* getGrContext() {
return fCurContext;
}
+
+ virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
+ return fCurRenderTarget;
+ }
+
private:
GrContext* fCurContext;
const GrGLInterface* fCurIntf;
GrRenderTarget* fCurRenderTarget;
SkOSWindow::SkBackEndTypes fBackend;
+ int fMSAASampleCount;
typedef SampleWindow::DeviceManager INHERITED;
};
@@ -645,9 +653,10 @@
}
static void usage(const char * argv0) {
- SkDebugf("%s [--slide sampleName] [-i resourcePath]\n", argv0);
+ SkDebugf("%s [--slide sampleName] [-i resourcePath] [-msaa sampleCount]\n", argv0);
SkDebugf(" sampleName: sample at which to start.\n");
SkDebugf(" resourcePath: directory that stores image resources.\n");
+ SkDebugf(" msaa: request multisampling with the given sample count.\n");
}
SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager) : INHERITED(hwnd) {
@@ -663,6 +672,7 @@
const char* resourcePath = NULL;
fCurrIndex = -1;
+ fMSAASampleCount = 0;
const char* const commandName = argv[0];
char* const* stop = argv + argc;
@@ -680,7 +690,12 @@
fprintf(stderr, "Unknown sample \"%s\"\n", *argv);
}
}
- }
+ } else if (strcmp(*argv, "--msaa") == 0) {
+ ++argv;
+ if (argv < stop && **argv) {
+ fMSAASampleCount = atoi(*argv);
+ }
+ }
else {
usage(commandName);
}
@@ -820,7 +835,7 @@
devManager->ref();
fDevManager = devManager;
}
- fDevManager->setUpBackend(this);
+ fDevManager->setUpBackend(this, fMSAASampleCount);
// If another constructor set our dimensions, ensure that our
// onSizeChange gets called.
@@ -1671,7 +1686,7 @@
fDeviceType = type;
- fDevManager->setUpBackend(this);
+ fDevManager->setUpBackend(this, fMSAASampleCount);
this->updateTitle();
this->inval(NULL);
@@ -1867,6 +1882,16 @@
"null-gl: "
};
+static const bool gDeviceTypeIsGPU[] = {
+ false,
+ false,
+ true,
+#if SK_ANGLE
+ true,
+#endif
+ true
+};
+
static const char* trystate_str(SkOSMenu::TriState state,
const char trueStr[], const char falseStr[]) {
if (SkOSMenu::kOnState == state) {
@@ -1926,6 +1951,12 @@
title.prepend("! ");
}
+ if (gDeviceTypeIsGPU[fDeviceType] &&
+ fDevManager->getGrRenderTarget()->numSamples() > 0) {
+ title.appendf(" [MSAA: %d]",
+ fDevManager->getGrRenderTarget()->numSamples());
+ }
+
this->setTitle(title.c_str());
}
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index ba404da..0a7b3cf 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -50,7 +50,7 @@
*/
class DeviceManager : public SkRefCnt {
public:
- virtual void setUpBackend(SampleWindow* win) = 0;
+ virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) = 0;
virtual void tearDownBackend(SampleWindow* win) = 0;
@@ -72,6 +72,9 @@
// return the GrContext backing gpu devices
virtual GrContext* getGrContext() = 0;
+
+ // return the GrRenderTarget backing gpu devices
+ virtual GrRenderTarget* getGrRenderTarget() = 0;
};
SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
@@ -170,6 +173,8 @@
SkOSMenu::TriState fHintingState;
unsigned fFlipAxis;
+ int fMSAASampleCount;
+
int fScrollTestX, fScrollTestY;
SkScalar fZoomCenterX, fZoomCenterY;
diff --git a/src/views/ios/SkOSWindow_iOS.mm b/src/views/ios/SkOSWindow_iOS.mm
index 81ae37c..8813625 100755
--- a/src/views/ios/SkOSWindow_iOS.mm
+++ b/src/views/ios/SkOSWindow_iOS.mm
@@ -54,7 +54,8 @@
[(SkUIView*)fHWND onUpdateMenu:menu];
}
-bool SkOSWindow::attach(SkBackEndTypes /* attachType */) {
+bool SkOSWindow::attach(SkBackEndTypes /* attachType */,
+ int /* msaaSampleCount */) {
bool success = true;
return success;
}
diff --git a/src/views/mac/SkNSView.h b/src/views/mac/SkNSView.h
index 60727eb..bf6e67c 100644
--- a/src/views/mac/SkNSView.h
+++ b/src/views/mac/SkNSView.h
@@ -42,7 +42,7 @@
- (void)postInvalWithRect:(const SkIRect*)rectOrNil;
- (BOOL)onHandleEvent:(const SkEvent&)event;
-- (bool)attach:(SkOSWindow::SkBackEndTypes)attachType;
+- (bool)attach:(SkOSWindow::SkBackEndTypes)attachType withMSAASampleCount:(int) sampleCount;
- (void)detach;
- (void)present;
@end
diff --git a/src/views/mac/SkNSView.mm b/src/views/mac/SkNSView.mm
index 30488ab..1e7be69 100644
--- a/src/views/mac/SkNSView.mm
+++ b/src/views/mac/SkNSView.mm
@@ -226,25 +226,36 @@
#include <OpenGL/OpenGL.h>
namespace {
-CGLContextObj createGLContext() {
+CGLContextObj createGLContext(int msaaSampleCount) {
GLint major, minor;
CGLGetVersion(&major, &minor);
- const CGLPixelFormatAttribute attributes[] = {
- kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
-#if USE_MSAA
- kCGLPFASampleBuffers, 1,
- kCGLPFAMultisample,
- kCGLPFASamples, 8,
-#endif
+ static const CGLPixelFormatAttribute attributes[] = {
+ kCGLPFAStencilSize, (CGLPixelFormatAttribute) 8,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatObj format;
- GLint npix;
- CGLChoosePixelFormat(attributes, &format, &npix);
+ GLint npix = 0;
+ if (msaaSampleCount > 0) {
+ static int kAttributeCount = SK_ARRAY_COUNT(attributes);
+ CGLPixelFormatAttribute msaaAttributes[kAttributeCount + 5];
+ memcpy(msaaAttributes, attributes, sizeof(attributes));
+ SkASSERT(0 == msaaAttributes[kAttributeCount - 1]);
+ msaaAttributes[kAttributeCount - 1] = kCGLPFASampleBuffers;
+ msaaAttributes[kAttributeCount + 0] = (CGLPixelFormatAttribute)1;
+ msaaAttributes[kAttributeCount + 1] = kCGLPFAMultisample;
+ msaaAttributes[kAttributeCount + 2] = kCGLPFASamples;
+ msaaAttributes[kAttributeCount + 3] =
+ (CGLPixelFormatAttribute)msaaSampleCount;
+ msaaAttributes[kAttributeCount + 4] = (CGLPixelFormatAttribute)0;
+ CGLChoosePixelFormat(msaaAttributes, &format, &npix);
+ }
+ if (!npix) {
+ CGLChoosePixelFormat(attributes, &format, &npix);
+ }
CGLContextObj ctx;
CGLCreateContext(format, NULL, &ctx);
@@ -267,9 +278,10 @@
[fGLContext setView:self];
}
}
-- (bool)attach:(SkOSWindow::SkBackEndTypes)attachType {
+- (bool)attach:(SkOSWindow::SkBackEndTypes)attachType
+ withMSAASampleCount:(int) sampleCount {
if (nil == fGLContext) {
- CGLContextObj ctx = createGLContext();
+ CGLContextObj ctx = createGLContext(sampleCount);
fGLContext = [[NSOpenGLContext alloc] initWithCGLContextObj:ctx];
CGLReleaseContext(ctx);
if (NULL == fGLContext) {
diff --git a/src/views/mac/SkOSWindow_Mac.mm b/src/views/mac/SkOSWindow_Mac.mm
index 4aa4eb5..a5d3fef 100644
--- a/src/views/mac/SkOSWindow_Mac.mm
+++ b/src/views/mac/SkOSWindow_Mac.mm
@@ -63,8 +63,8 @@
[(SkNSView*)fHWND onUpdateMenu:menu];
}
-bool SkOSWindow::attach(SkBackEndTypes attachType) {
- return [(SkNSView*)fHWND attach:attachType];
+bool SkOSWindow::attach(SkBackEndTypes attachType, int sampleCount) {
+ return [(SkNSView*)fHWND attach:attachType withMSAASampleCount:sampleCount];
}
void SkOSWindow::detach() {
diff --git a/src/views/unix/SkOSWindow_Unix.cpp b/src/views/unix/SkOSWindow_Unix.cpp
index 66b1694..c8fc2c7 100644
--- a/src/views/unix/SkOSWindow_Unix.cpp
+++ b/src/views/unix/SkOSWindow_Unix.cpp
@@ -34,53 +34,109 @@
SkOSWindow::SkOSWindow(void* unused)
: INHERITED()
- , fVi(0) {
- fUnixWindow.fDisplay = XOpenDisplay(NULL);
+ , fVi(NULL)
+ , fMSAASampleCount(0) {
+ fUnixWindow.fDisplay = NULL;
fUnixWindow.fGLContext = NULL;
- Display* dsp = fUnixWindow.fDisplay;
- if (dsp) {
- // Attempt to create a window that supports GL
- GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER,
- GLX_STENCIL_SIZE, 8, None };
- fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att);
- if (fVi) {
- Colormap colorMap = XCreateColormap(dsp, RootWindow(dsp, fVi->screen),
- fVi->visual, AllocNone);
- XSetWindowAttributes swa;
- swa.colormap = colorMap;
- swa.event_mask = EVENT_MASK;
- fUnixWindow.fWin = XCreateWindow(dsp, RootWindow(dsp, fVi->screen),
- 0, 0, WIDTH, HEIGHT, 0, fVi->depth,
- InputOutput, fVi->visual, CWEventMask | CWColormap, &swa);
-
- } else {
- // Create a simple window instead. We will not be able to
- // show GL
- fUnixWindow.fWin = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp),
- 0, 0, WIDTH, HEIGHT, 0, 0, 0);
- }
- mapWindowAndWait();
- fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL);
- }
+ this->initWindow(0);
this->resize(WIDTH, HEIGHT);
}
SkOSWindow::~SkOSWindow() {
+ this->closeWindow();
+}
+
+void SkOSWindow::closeWindow() {
if (NULL != fUnixWindow.fDisplay) {
- if (NULL != fUnixWindow.fGLContext) {
- glXMakeCurrent(fUnixWindow.fDisplay, None, NULL);
- glXDestroyContext(fUnixWindow.fDisplay, fUnixWindow.fGLContext);
- }
+ this->detach();
+ SkASSERT(NULL != fUnixWindow.fGc);
XFreeGC(fUnixWindow.fDisplay, fUnixWindow.fGc);
+ fUnixWindow.fGc = NULL;
XDestroyWindow(fUnixWindow.fDisplay, fUnixWindow.fWin);
+ fVi = NULL;
XCloseDisplay(fUnixWindow.fDisplay);
- fUnixWindow.fDisplay = 0;
+ fUnixWindow.fDisplay = NULL;
+ fMSAASampleCount = 0;
}
}
+void SkOSWindow::initWindow(int requestedMSAASampleCount) {
+ if (fMSAASampleCount != requestedMSAASampleCount) {
+ this->closeWindow();
+ }
+ // presence of fDisplay means we already have a window
+ if (NULL != fUnixWindow.fDisplay) {
+ return;
+ }
+ fUnixWindow.fDisplay = XOpenDisplay(NULL);
+ Display* dsp = fUnixWindow.fDisplay;
+ if (NULL == dsp) {
+ SkDebugf("Could not open an X Display");
+ return;
+ }
+ // Attempt to create a window that supports GL
+ GLint att[] = {
+ GLX_RGBA,
+ GLX_DEPTH_SIZE, 24,
+ GLX_DOUBLEBUFFER,
+ GLX_STENCIL_SIZE, 8,
+ None
+ };
+ SkASSERT(NULL == fVi);
+ if (requestedMSAASampleCount > 0) {
+ static const GLint kAttCount = SK_ARRAY_COUNT(att);
+ GLint msaaAtt[kAttCount + 4];
+ memcpy(msaaAtt, att, sizeof(att));
+ SkASSERT(None == msaaAtt[kAttCount - 1]);
+ msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
+ msaaAtt[kAttCount + 0] = 1;
+ msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
+ msaaAtt[kAttCount + 2] = requestedMSAASampleCount;
+ msaaAtt[kAttCount + 3] = None;
+ fVi = glXChooseVisual(dsp, DefaultScreen(dsp), msaaAtt);
+ fMSAASampleCount = requestedMSAASampleCount;
+ }
+ if (NULL == fVi) {
+ fVi = glXChooseVisual(dsp, DefaultScreen(dsp), att);
+ fMSAASampleCount = 0;
+ }
+
+ if (fVi) {
+ Colormap colorMap = XCreateColormap(dsp,
+ RootWindow(dsp, fVi->screen),
+ fVi->visual,
+ AllocNone);
+ XSetWindowAttributes swa;
+ swa.colormap = colorMap;
+ swa.event_mask = EVENT_MASK;
+ fUnixWindow.fWin = XCreateWindow(dsp,
+ RootWindow(dsp, fVi->screen),
+ 0, 0, // x, y
+ WIDTH, HEIGHT,
+ 0, // border width
+ fVi->depth,
+ InputOutput,
+ fVi->visual,
+ CWEventMask | CWColormap,
+ &swa);
+ } else {
+ // Create a simple window instead. We will not be able to show GL
+ fUnixWindow.fWin = XCreateSimpleWindow(dsp,
+ DefaultRootWindow(dsp),
+ 0, 0, // x, y
+ WIDTH, HEIGHT,
+ 0, // border width
+ 0, // border value
+ 0); // background value
+ }
+ this->mapWindowAndWait();
+ fUnixWindow.fGc = XCreateGC(dsp, fUnixWindow.fWin, 0, NULL);
+}
+
+
void SkOSWindow::post_linuxevent() {
// Put an event in the X queue to fire an SkEvent.
- if (!fUnixWindow.fDisplay) {
+ if (NULL == fUnixWindow.fDisplay) {
return;
}
long event_mask = NoEventMask;
@@ -97,6 +153,9 @@
void SkOSWindow::loop() {
Display* dsp = fUnixWindow.fDisplay;
+ if (NULL == dsp) {
+ return;
+ }
XSelectInput(dsp, fUnixWindow.fWin, EVENT_MASK);
bool loop = true;
@@ -153,6 +212,7 @@
}
void SkOSWindow::mapWindowAndWait() {
+ SkASSERT(NULL != fUnixWindow.fDisplay);
Display* dsp = fUnixWindow.fDisplay;
Window win = fUnixWindow.fWin;
XMapWindow(dsp, win);
@@ -168,11 +228,13 @@
}
-bool SkOSWindow::attach(SkBackEndTypes /* attachType */) {
+bool SkOSWindow::attach(SkBackEndTypes /* attachType */, int msaaSampleCount) {
+ this->initWindow(msaaSampleCount);
+ if (NULL == fUnixWindow.fDisplay) {
+ return false;
+ }
if (NULL == fUnixWindow.fGLContext) {
- if (NULL == fUnixWindow.fDisplay || NULL == fVi) {
- return false;
- }
+ SkASSERT(NULL != fVi);
fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay,
fVi,
@@ -209,7 +271,7 @@
}
void SkOSWindow::onSetTitle(const char title[]) {
- if (!fUnixWindow.fDisplay) {
+ if (NULL == fUnixWindow.fDisplay) {
return;
}
XTextProperty textProp;
@@ -253,16 +315,26 @@
}
void SkOSWindow::doPaint() {
- if (!fUnixWindow.fDisplay) return;
+ if (NULL == fUnixWindow.fDisplay) {
+ return;
+ }
// Draw the bitmap to the screen.
const SkBitmap& bitmap = getBitmap();
int width = bitmap.width();
int height = bitmap.height();
XImage image;
- if (!convertBitmapToXImage(image, bitmap)) return;
+ if (!convertBitmapToXImage(image, bitmap)) {
+ return;
+ }
- XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, 0, 0, width, height);
+ XPutImage(fUnixWindow.fDisplay,
+ fUnixWindow.fWin,
+ fUnixWindow.fGc,
+ &image,
+ 0, 0, // src x,y
+ 0, 0, // dst x,y
+ width, height);
}
bool SkOSWindow::onHandleChar(SkUnichar) {
diff --git a/src/views/win/SkOSWindow_win.cpp b/src/views/win/SkOSWindow_win.cpp
index d5aebea..6b26400 100644
--- a/src/views/win/SkOSWindow_win.cpp
+++ b/src/views/win/SkOSWindow_win.cpp
@@ -308,7 +308,7 @@
#define USE_MSAA 0
-HGLRC create_gl(HWND hwnd) {
+HGLRC create_gl(HWND hwnd, int msaaSampleCount) {
HDC dc = GetDC(hwnd);
@@ -323,7 +323,7 @@
int format = 0;
- GLint iattrs[] = {
+ static const GLint iAttrs[] = {
SK_WGL_DRAW_TO_WINDOW, TRUE,
SK_WGL_DOUBLE_BUFFER, TRUE,
SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
@@ -331,40 +331,40 @@
SK_WGL_COLOR_BITS, 24,
SK_WGL_ALPHA_BITS, 8,
SK_WGL_STENCIL_BITS, 8,
-
- // these must be kept last
- SK_WGL_SAMPLE_BUFFERS, TRUE,
- SK_WGL_SAMPLES, 0,
- 0,0
+ 0, 0
};
- static const int kSampleBuffersValueIdx = SK_ARRAY_COUNT(iattrs) - 5;
- static const int kSamplesValueIdx = SK_ARRAY_COUNT(iattrs) - 3;
- if (USE_MSAA && extensions.hasExtension(dc, "WGL_ARB_multisample")) {
- for (int samples = 16; samples > 1; --samples) {
-
- iattrs[kSamplesValueIdx] = samples;
- GLfloat fattrs[] = {0,0};
- GLuint num;
- int formats[64];
- extensions.choosePixelFormat(dc, iattrs, fattrs, 64, formats, &num);
- num = min(num,64);
- for (GLuint i = 0; i < num; ++i) {
- DescribePixelFormat(dc, formats[i], sizeof(pfd), &pfd);
- if (SetPixelFormat(dc, formats[i], &pfd)) {
- format = formats[i];
- break;
- }
+ GLfloat fAttrs[] = {0, 0};
+
+ if (msaaSampleCount > 0 &&
+ extensions.hasExtension(dc, "WGL_ARB_multisample")) {
+ static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
+ GLint msaaIAttrs[kIAttrsCount + 4];
+ memcpy(msaaIAttrs, iAttrs, sizeof(GLint) * kIAttrsCount);
+ SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] &&
+ 0 == msaaIAttrs[kIAttrsCount - 1]);
+ msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS;
+ msaaIAttrs[kIAttrsCount - 1] = TRUE;
+ msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES;
+ msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount;
+ msaaIAttrs[kIAttrsCount + 2] = 0;
+ msaaIAttrs[kIAttrsCount + 3] = 0;
+ GLuint num;
+ int formats[64];
+ extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
+ num = min(num,64);
+ for (GLuint i = 0; i < num; ++i) {
+ DescribePixelFormat(dc, formats[i], sizeof(pfd), &pfd);
+ if (SetPixelFormat(dc, formats[i], &pfd)) {
+ format = formats[i];
+ break;
}
}
}
if (0 == format) {
- iattrs[kSampleBuffersValueIdx-1] = iattrs[kSampleBuffersValueIdx] = 0;
- iattrs[kSamplesValueIdx-1] = iattrs[kSamplesValueIdx] = 0;
- GLfloat fattrs[] = {0,0};
GLuint num;
- extensions.choosePixelFormat(dc, iattrs, fattrs, 1, &format, &num);
+ extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num);
DescribePixelFormat(dc, format, sizeof(pfd), &pfd);
BOOL set = SetPixelFormat(dc, format, &pfd);
SkASSERT(TRUE == set);
@@ -377,9 +377,9 @@
return glrc;
}
-bool SkOSWindow::attachGL() {
+bool SkOSWindow::attachGL(int msaaSampleCount) {
if (NULL == fHGLRC) {
- fHGLRC = create_gl((HWND)fHWND);
+ fHGLRC = create_gl((HWND)fHWND, msaaSampleCount);
if (NULL == fHGLRC) {
return false;
}
@@ -408,13 +408,16 @@
}
#if SK_ANGLE
-bool create_ANGLE(EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
- EGLContext* eglContext, EGLSurface* eglSurface) {
- EGLint contextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
+bool create_ANGLE(EGLNativeWindowType hWnd,
+ int msaaSampleCount,
+ EGLDisplay* eglDisplay,
+ EGLContext* eglContext,
+ EGLSurface* eglSurface) {
+ static const EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE, EGL_NONE
};
- EGLint configAttribList[] = {
+ static const EGLint configAttribList[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
@@ -423,7 +426,7 @@
EGL_STENCIL_SIZE, 8,
EGL_NONE
};
- EGLint surfaceAttribList[] = {
+ static const EGLint surfaceAttribList[] = {
EGL_NONE, EGL_NONE
};
@@ -445,9 +448,31 @@
// Choose config
EGLConfig config;
- if (!eglChooseConfig(display, configAttribList,
- &config, 1, &numConfigs)) {
- return false;
+ bool foundConfig = false;
+ if (msaaSampleCount) {
+ static const int kConfigAttribListCnt =
+ SK_ARRAY_COUNT(configAttribList);
+ EGLint msaaConfigAttribList[kConfigAttribListCnt + 4];
+ memcpy(msaaConfigAttribList,
+ configAttribList,
+ sizeof(configAttribList));
+ SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]);
+ msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS;
+ msaaConfigAttribList[kConfigAttribListCnt + 0] = 1;
+ msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES;
+ msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount;
+ msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE;
+ if (eglChooseConfig(display, configAttribList,
+ &config, 1, &numConfigs)) {
+ SkASSERT(numConfigs > 0);
+ foundConfig = true;
+ }
+ }
+ if (!foundConfig) {
+ if (!eglChooseConfig(display, configAttribList,
+ &config, 1, &numConfigs)) {
+ return false;
+ }
}
// Create a surface
@@ -477,9 +502,13 @@
return true;
}
-bool SkOSWindow::attachANGLE() {
+bool SkOSWindow::attachANGLE(int msaaSampleCount) {
if (EGL_NO_DISPLAY == fDisplay) {
- bool bResult = create_ANGLE((HWND)fHWND, &fDisplay, &fContext, &fSurface);
+ bool bResult = create_ANGLE((HWND)fHWND,
+ msaaSampleCount,
+ &fDisplay,
+ &fContext,
+ &fSurface);
if (false == bResult) {
return false;
}
@@ -489,7 +518,7 @@
GR_GL_CALL(intf, ClearStencil(0));
GR_GL_CALL(intf, ClearColor(0, 0, 0, 0));
GR_GL_CALL(intf, StencilMask(0xffffffff));
- GR_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT));
+ GR_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT));
}
}
if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
@@ -529,7 +558,7 @@
#endif
// return true on success
-bool SkOSWindow::attach(SkBackEndTypes attachType) {
+bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount) {
// attach doubles as "windowResize" so we need to allo
// already bound states to pass through again
@@ -542,11 +571,11 @@
// nothing to do
break;
case kNativeGL_BackEndType:
- result = attachGL();
+ result = attachGL(msaaSampleCount);
break;
#if SK_ANGLE
case kANGLE_BackEndType:
- result = attachANGLE();
+ result = attachANGLE(msaaSampleCount);
break;
#endif
default: