From d47fafe05743d61958397bcf7a4b2bf66d778e1d Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 20 Oct 2011 21:09:45 +0000 Subject: [PATCH] Add test that validates GrGLInterfaces Review URL: http://codereview.appspot.com/5304048/ git-svn-id: http://skia.googlecode.com/svn/trunk@2510 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/tests.gyp | 1 + include/gpu/GrGLInterface.h | 9 ++++++ include/gpu/SkGLContext.h | 3 ++ include/gpu/SkMesaGLContext.h | 19 ++++++++++-- include/gpu/SkNativeGLContext.h | 18 +++++++++++ src/gpu/mac/SkNativeGLContext_mac.cpp | 10 ++++++ src/gpu/mesa/SkMesaGLContext.cpp | 17 ++++++++++ src/gpu/unix/SkNativeGLContext_unix.cpp | 13 ++++++++ src/gpu/win/SkNativeGLContext_win.cpp | 17 ++++++++-- tests/GLInterfaceValidation.cpp | 55 +++++++++++++++++++++++++++++++++ tests/Test.cpp | 3 ++ 11 files changed, 160 insertions(+), 5 deletions(-) create mode 100755 tests/GLInterfaceValidation.cpp diff --git a/gyp/tests.gyp b/gyp/tests.gyp index c5c3ff6..ede5885 100644 --- a/gyp/tests.gyp +++ b/gyp/tests.gyp @@ -30,6 +30,7 @@ '../tests/FillPathTest.cpp', '../tests/FlateTest.cpp', '../tests/GeometryTest.cpp', + '../tests/GLInterfaceValidation.cpp', '../tests/GLProgramsTest.cpp', '../tests/InfRectTest.cpp', '../tests/MathTest.cpp', diff --git a/include/gpu/GrGLInterface.h b/include/gpu/GrGLInterface.h index b3e0cf1..20b74ab 100644 --- a/include/gpu/GrGLInterface.h +++ b/include/gpu/GrGLInterface.h @@ -69,8 +69,17 @@ struct GrGLInterface; const GrGLInterface* GrGLDefaultInterface(); +/** + * Creates a GrGLInterface for a "native" GL context (e.g. WGL on windows, + * GLX on linux, AGL on Mac). On platforms that have context-specific function + * pointers for GL extensions (e.g. windows) the returned interface is only + * valid for the context that was current at creation. + */ const GrGLInterface* GrGLCreateNativeInterface(); +/** + * Creates a GrGLInterface for an OSMesa context. + */ const GrGLInterface* GrGLCreateMesaInterface(); typedef unsigned int GrGLenum; diff --git a/include/gpu/SkGLContext.h b/include/gpu/SkGLContext.h index d36a9f9..f92a770 100644 --- a/include/gpu/SkGLContext.h +++ b/include/gpu/SkGLContext.h @@ -20,6 +20,9 @@ public: SkGLContext(); virtual ~SkGLContext(); + /** + * Initializes the context and makes it current. + */ bool init(const int width, const int height); int getFBOID() const { return fFBO; } diff --git a/include/gpu/SkMesaGLContext.h b/include/gpu/SkMesaGLContext.h index 4351f66..b7578f3 100644 --- a/include/gpu/SkMesaGLContext.h +++ b/include/gpu/SkMesaGLContext.h @@ -13,6 +13,9 @@ #if SK_MESA class SkMesaGLContext : public SkGLContext { +private: + typedef intptr_t Context; + public: SkMesaGLContext(); @@ -20,16 +23,28 @@ public: virtual void makeCurrent() const SK_OVERRIDE; + class AutoContextRestore { + public: + AutoContextRestore(); + ~AutoContextRestore(); + + private: + Context fOldContext; + GLint fOldWidth; + GLint fOldHeight; + GLint fOldFormat; + void* fOldImage; + }; + protected: virtual const GrGLInterface* createGLContext() SK_OVERRIDE; void destroyGLContext() SK_OVERRIDE; private: - typedef intptr_t Context; Context fContext; GrGLubyte *fImage; }; #endif -#endif \ No newline at end of file +#endif diff --git a/include/gpu/SkNativeGLContext.h b/include/gpu/SkNativeGLContext.h index 512e66a..f2037cf 100644 --- a/include/gpu/SkNativeGLContext.h +++ b/include/gpu/SkNativeGLContext.h @@ -28,6 +28,24 @@ public: virtual void makeCurrent() const SK_OVERRIDE; + class AutoContextRestore { + public: + AutoContextRestore(); + ~AutoContextRestore(); + + private: + #if defined(SK_BUILD_FOR_MAC) + AGLContext fOldAGLContext; + #elif defined(SK_BUILD_FOR_UNIX) + GLXContext fOldGLXContext; + Display* fOldDisplay; + GLXDrawable fOldDrawable; + #elif defined(SK_BUILD_FOR_WIN32) + HDC fOldHDC; + HGLRC fOldHGLRC; + #endif + }; + protected: virtual const GrGLInterface* createGLContext() SK_OVERRIDE; void destroyGLContext() SK_OVERRIDE; diff --git a/src/gpu/mac/SkNativeGLContext_mac.cpp b/src/gpu/mac/SkNativeGLContext_mac.cpp index 3f864c2..ad68c40 100644 --- a/src/gpu/mac/SkNativeGLContext_mac.cpp +++ b/src/gpu/mac/SkNativeGLContext_mac.cpp @@ -7,6 +7,16 @@ */ #include "SkNativeGLContext.h" +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldAGLContext = aglGetCurrentContext(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + aglSetCurrentContext(fOldAGLContext); +} + +/////////////////////////////////////////////////////////////////////////////// + SkNativeGLContext::SkNativeGLContext() : fContext(NULL) { } diff --git a/src/gpu/mesa/SkMesaGLContext.cpp b/src/gpu/mesa/SkMesaGLContext.cpp index 23ccc95..5440a90 100644 --- a/src/gpu/mesa/SkMesaGLContext.cpp +++ b/src/gpu/mesa/SkMesaGLContext.cpp @@ -10,6 +10,23 @@ #include "SkMesaGLContext.h" +SkMesaGLContext::AutoContextRestore::AutoContextRestore() { + fOldContext = (Context)OSMesaGetCurrentContext(); + if (NULL != (OSMesaContext)fOldContext) { + OSMesaGetColorBuffer((OSMesaContext)fOldContext, + &fOldWidth, &fOldHeight, + &fOldFormat, &fOldImage); + } +} + +SkMesaGLContext::AutoContextRestore::~AutoContextRestore() { + if (NULL != fOldContext) { + OSMesaMakeCurrent((OSMesaContext)fOldContext, fOldImage, + fOldFormat, fOldWidth, fOldHeight); + } +} + +/////////////////////////////////////////////////////////////////////////////// SkMesaGLContext::SkMesaGLContext() : fContext(NULL) diff --git a/src/gpu/unix/SkNativeGLContext_unix.cpp b/src/gpu/unix/SkNativeGLContext_unix.cpp index 870ff45..907e2b8 100644 --- a/src/gpu/unix/SkNativeGLContext_unix.cpp +++ b/src/gpu/unix/SkNativeGLContext_unix.cpp @@ -9,6 +9,19 @@ #include +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldGLXContext = glXGetCurrentContext(); + fOldDisplay = glXGetCurrentDisplay(); + fOldDrawable = glXGetCurrentDrawable(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + if (NULL != fOldDisplay) { + glXMakeCurrent(fOldDisplay, fOldDrawable, fOldGLXContext); + } +} + +/////////////////////////////////////////////////////////////////////////////// static bool ctxErrorOccurred = false; static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { diff --git a/src/gpu/win/SkNativeGLContext_win.cpp b/src/gpu/win/SkNativeGLContext_win.cpp index c19f7cc..5d518dd 100644 --- a/src/gpu/win/SkNativeGLContext_win.cpp +++ b/src/gpu/win/SkNativeGLContext_win.cpp @@ -11,12 +11,23 @@ #define WIN32_LEAN_AND_MEAN #include +SkNativeGLContext::AutoContextRestore::AutoContextRestore() { + fOldHGLRC = wglGetCurrentContext(); + fOldHDC = wglGetCurrentDC(); +} + +SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { + wglMakeCurrent(fOldHDC, fOldHGLRC); +} + +/////////////////////////////////////////////////////////////////////////////// + ATOM SkNativeGLContext::gWC = 0; SkNativeGLContext::SkNativeGLContext() - : fWindow(NULL) - , fDeviceContext(NULL) - , fGlRenderContext(0) { + : fWindow(NULL) + , fDeviceContext(NULL) + , fGlRenderContext(0) { } SkNativeGLContext::~SkNativeGLContext() { diff --git a/tests/GLInterfaceValidation.cpp b/tests/GLInterfaceValidation.cpp new file mode 100755 index 0000000..a18ab84 --- /dev/null +++ b/tests/GLInterfaceValidation.cpp @@ -0,0 +1,55 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Test.h" +#include "SkNativeGLContext.h" +#include "SkMesaGLContext.h" + +static void GLInterfaceValidationTest(skiatest::Reporter* reporter) { + typedef const GrGLInterface* (*interfaceFactory)(); + struct { + interfaceFactory fFactory; + const char* fName; + } interfaceFactories[] = { + {GrGLCreateNativeInterface, "Native"}, +#if SK_MESA + {GrGLCreateMesaInterface, "Mesa"}, +#endif + }; + + // On some platforms GrGLCreateNativeInterface will fail unless an OpenGL + // context has been created. Also, preserve the current context that may + // be in use by outer test harness. + SkNativeGLContext::AutoContextRestore nglacr; + SkNativeGLContext nglctx; + static const int gBOGUS_SIZE = 16; + REPORTER_ASSERT(reporter, nglctx.init(gBOGUS_SIZE, gBOGUS_SIZE)); +#if SK_MESA + // We must have a current OSMesa context to initialize an OSMesa + // GrGLInterface + SkMesaGLContext::AutoContextRestore mglacr; + SkMesaGLContext mglctx; + REPORTER_ASSERT(reporter, mglctx.init(gBOGUS_SIZE, gBOGUS_SIZE)); +#endif + + SkAutoTUnref iface; + for (size_t i = 0; i < SK_ARRAY_COUNT(interfaceFactories); ++i) { + iface.reset(interfaceFactories[i].fFactory()); + REPORTER_ASSERT(reporter, NULL != iface.get()); + if (iface.get()) { + REPORTER_ASSERT(reporter, iface.get()->validate(kOpenGL_Shaders_GrEngine)); + } + } +} + + +#include "TestClassDef.h" +DEFINE_TESTCLASS("GLInterfaceValidation", + GLInterfaceValidationTestClass, + GLInterfaceValidationTest) + diff --git a/tests/Test.cpp b/tests/Test.cpp index d91eeed..1c3b691 100644 --- a/tests/Test.cpp +++ b/tests/Test.cpp @@ -89,6 +89,9 @@ GrContext* GpuTest::GetContext() { gGrContext.reset(GrContext::Create(kOpenGL_Shaders_GrEngine, ctx)); } } + if (gGLContext.get()) { + gGLContext.get()->makeCurrent(); + } return gGrContext.get(); } -- 2.7.4