diff -r 0be82064630b -r 2bf8a359aa2f egl/sfopenvg/riMiniEGL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfopenvg/riMiniEGL.h Wed May 12 11:20:41 2010 +0100 @@ -0,0 +1,391 @@ +#ifndef __RIMINIEGL_H +#define __RIMINIEGL_H + +/*------------------------------------------------------------------------ + * + * EGL 1.3 + * ------- + * + * Copyright (c) 2007 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and /or associated documentation files + * (the "Materials "), to deal in the Materials without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Materials, + * and to permit persons to whom the Materials are furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR + * THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//** + * \file + * \brief Simple implementation of EGL 1.3 + * \note caveats: + - always renders into the backbuffer and blits it to window (no single buffered rendering) + - no native Windows or Mac OS X pixmap support + - no power management events + - no support for swap interval + * \todo what happens in egl functions when eglTerminate has been called but the context and surface are still in use? + * \todo OSDeinitMutex should be called in case getEGL fails. + *//*-------------------------------------------------------------------*/ +#include +#include "egl.h" +#include "openvg.h" +#include "riArray.h" +#include "riMath.h" +#include "riContext.h" +#include "riImage.h" + +#ifdef BUILD_WITH_PRIVATE_EGL +#include "eglinternal.h" +#endif + +#ifdef BUILD_WITH_PRIVATE_OPENVG +#include "openvginternal.h" +#endif + +//============================================================================================== + +namespace OpenVGRI +{ +void* OSGetCurrentThreadID(void); +void OSAcquireMutex(void); +void OSReleaseMutex(void); +void OSDeinitMutex(void); + +EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id); +void* OSCreateWindowContext(EGLNativeWindowType window); +void OSDestroyWindowContext(void* context); +bool OSIsWindow(const void* context); +void OSGetWindowSize(const void* context, int& width, int& height); +void OSBlitToWindow(void* context, const Drawable* drawable); +EGLBoolean OSGetNativePixmapInfo(NativePixmapType pixmap, int* width, int* height, int* stride, VGImageFormat* format, int** data); + + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +class RIEGLConfig +{ +public: + RIEGLConfig() : m_desc(Color::formatToDescriptor(VG_sRGBA_8888)), m_configID(0) {} + ~RIEGLConfig() {} + void set(int r, int g, int b, int a, int l, int bpp, int samples, int maskBits, int ID) + { + m_desc.redBits = r; + m_desc.greenBits = g; + m_desc.blueBits = b; + m_desc.alphaBits = a; + m_desc.luminanceBits = l; + m_desc.alphaShift = 0; + m_desc.luminanceShift = 0; + m_desc.blueShift = b ? a : 0; + m_desc.greenShift = g ? a + b : 0; + m_desc.redShift = r ? a + b + g : 0; + m_desc.format = (VGImageFormat)-1; + m_desc.internalFormat = l ? Color::sLA : Color::sRGBA; + m_desc.bitsPerPixel = bpp; + RI_ASSERT(Color::isValidDescriptor(m_desc)); + m_samples = samples; + m_maskBits = maskBits; + m_configID = ID; + m_config = (EGLConfig)ID; + } + + Color::Descriptor configToDescriptor(bool sRGB, bool premultiplied) const + { + Color::Descriptor desc = m_desc; + unsigned int f = m_desc.luminanceBits ? Color::LUMINANCE : 0; + f |= sRGB ? Color::NONLINEAR : 0; + f |= premultiplied ? Color::PREMULTIPLIED : 0; + desc.internalFormat = (Color::InternalFormat)f; + return desc; + } + + //EGL RED SIZE bits of Red in the color buffer + //EGL GREEN SIZE bits of Green in the color buffer + //EGL BLUE SIZE bits of Blue in the color buffer + //EGL ALPHA SIZE bits of Alpha in the color buffer + //EGL LUMINANCE SIZE bits of Luminance in the color buffer + Color::Descriptor m_desc; + int m_samples; + int m_maskBits; + EGLint m_configID; //EGL CONFIG ID unique EGLConfig identifier + EGLConfig m_config; + //EGL BUFFER SIZE depth of the color buffer (sum of channel bits) + //EGL ALPHA MASK SIZE number alpha mask bits (always 8) + //EGL BIND TO TEXTURE RGB boolean True if bindable to RGB textures. (always EGL_FALSE) + //EGL BIND TO TEXTURE RGBA boolean True if bindable to RGBA textures. (always EGL_FALSE) + //EGL COLOR BUFFER TYPE enum color buffer type (EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER) + //EGL CONFIG CAVEAT enum any caveats for the configuration (always EGL_NONE) + //EGL DEPTH SIZE integer bits of Z in the depth buffer (always 0) + //EGL LEVEL integer frame buffer level (always 0) + //EGL MAX PBUFFER WIDTH integer maximum width of pbuffer (always INT_MAX) + //EGL MAX PBUFFER HEIGHT integer maximum height of pbuffer (always INT_MAX) + //EGL MAX PBUFFER PIXELS integer maximum size of pbuffer (always INT_MAX) + //EGL MAX SWAP INTERVAL integer maximum swap interval (always 1) + //EGL MIN SWAP INTERVAL integer minimum swap interval (always 1) + //EGL NATIVE RENDERABLE boolean EGL TRUE if native rendering APIs can render to surface (always EGL_FALSE) + //EGL NATIVE VISUAL ID integer handle of corresponding native visual (always 0) + //EGL NATIVE VISUAL TYPE integer native visual type of the associated visual (always EGL_NONE) + //EGL RENDERABLE TYPE bitmask which client rendering APIs are supported. (always EGL_OPENVG_BIT) + //EGL SAMPLE BUFFERS integer number of multisample buffers (always 0) + //EGL SAMPLES integer number of samples per pixel (always 0) + //EGL STENCIL SIZE integer bits of Stencil in the stencil buffer (always 0) + //EGL SURFACE TYPE bitmask which types of EGL surfaces are supported. (always EGL WINDOW BIT | EGL PIXMAP BIT | EGL PBUFFER BIT) + //EGL TRANSPARENT TYPE enum type of transparency supported (always EGL_NONE) + //EGL TRANSPARENT RED VALUE integer transparent red value (undefined) + //EGL TRANSPARENT GREEN VALUE integer transparent green value (undefined) + //EGL TRANSPARENT BLUE VALUE integer transparent blue value (undefined) +}; + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +class RIEGLContext +{ +public: + RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config); + ~RIEGLContext(); + void addReference() { m_referenceCount++; } + int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } + + VGContext* getVGContext() const { return m_vgContext; } + EGLConfig getConfig() const { return m_config; } +private: + RIEGLContext(const RIEGLContext&); + RIEGLContext& operator=(const RIEGLContext&); + VGContext* m_vgContext; + const EGLConfig m_config; + int m_referenceCount; +}; + +RIEGLContext* CastToRIEGLContext(EGLContext aCtxId); +EGLContext CastFromRIEGLContext(RIEGLContext* aCtx); + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +class RIEGLSurface +{ +public: + RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer); + ~RIEGLSurface(); + void addReference() { m_referenceCount++; } + int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } + + void* getOSWindowContext() const { return m_OSWindowContext; } + EGLConfig getConfig() const { return m_config; } + Drawable* getDrawable() const { return m_drawable; } + bool isLargestPbuffer() const { return m_largestPbuffer; } + int getRenderBuffer() const { return m_renderBuffer; } + +private: + RIEGLSurface(const RIEGLSurface&); + RIEGLSurface& operator=(const RIEGLSurface&); + void* m_OSWindowContext; + const EGLConfig m_config; + Drawable* m_drawable; + bool m_largestPbuffer; + int m_renderBuffer; //EGL_BACK_BUFFER or EGL_SINGLE_BUFFER + int m_referenceCount; +}; + +RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId); +EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface); + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +#define EGL_NUMCONFIGS 60 + +class RIEGLDisplay +{ +public: + RIEGLDisplay(EGLDisplay id); + ~RIEGLDisplay(); + + int getNumConfigs() const { return EGL_NUMCONFIGS; } + const RIEGLConfig& getConfigByIdx(int i) const { RI_ASSERT(i >= 0 && i < EGL_NUMCONFIGS); return m_configs[i]; } + const RIEGLConfig& getConfig(const EGLConfig config) const { for(int i=0;i m_contexts; + Array m_surfaces; + + RIEGLConfig m_configs[EGL_NUMCONFIGS]; +}; + + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +class RIEGLThread +{ +public: + RIEGLThread(void* currentThreadID); + ~RIEGLThread(); + + void* getThreadID() const { return m_threadID; } + + void makeCurrent(RIEGLContext* c, RIEGLSurface* s) { m_context = c; m_surface = s; } + RIEGLContext* getCurrentContext() const { return m_context; } + RIEGLSurface* getCurrentSurface() const { return m_surface; } + + void setError(EGLint error) { m_error = error; } + EGLint getError() const { return m_error; } + + void bindAPI(EGLint api) { m_boundAPI = api; } + EGLint getBoundAPI() const { return m_boundAPI; } + +private: + RIEGLThread(const RIEGLThread&); + RIEGLThread operator=(const RIEGLThread&); + + RIEGLContext* m_context; + RIEGLSurface* m_surface; + EGLint m_error; + void* m_threadID; + EGLint m_boundAPI; +}; + + +Image* CastToImage(EGLClientBuffer aBufferId); +EGLClientBuffer CastFromImage(Image* aBUffer); + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +class EGL +{ +public: + EGL(); + ~EGL(); + + void addReference() { m_referenceCount++; } + int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } + + void addDisplay(RIEGLDisplay* display) { RI_ASSERT(display); m_displays.push_back(display); } //throws bad alloc + void removeDisplay(RIEGLDisplay* display) { RI_ASSERT(display); bool res = m_displays.remove(display); RI_ASSERT(res); RI_UNREF(res); } + RIEGLDisplay* getDisplay(const EGLDisplay displayID) const; + EGLDisplay findDisplay(const EGLContext ctx) const; + + void addCurrentThread(RIEGLThread* thread) { RI_ASSERT(thread); m_currentThreads.push_back(thread); } //throws bad alloc + void removeCurrentThread(RIEGLThread* thread) { RI_ASSERT(thread); bool res = m_currentThreads.remove(thread); RI_ASSERT(res); RI_UNREF(res); } + RIEGLThread* getCurrentThread() const; + + RIEGLThread* getThread(); + void destroyThread(); + + bool isInUse(const void* image) const; + +private: + EGL(const EGL&); // Not allowed. + const EGL& operator=(const EGL&); // Not allowed. + + Array m_threads; //threads that have called EGL + Array m_currentThreads; //threads that have a bound context + Array m_displays; + + int m_referenceCount; +}; + + +void* eglvgGetCurrentVGContext(void); +bool eglvgIsInUse(void* image); + +} //end of namespace + + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +#define EGL_GET_DISPLAY(DISPLAY, RETVAL) \ + OSAcquireMutex(); \ + EGL* egl = getEGL(); \ + if(!egl) \ + { \ + OSReleaseMutex(); \ + return RETVAL; \ + } \ + RIEGLDisplay* display = egl->getDisplay(DISPLAY); \ + +#define EGL_GET_EGL(RETVAL) \ + OSAcquireMutex(); \ + EGL* egl = getEGL(); \ + if(!egl) \ + { \ + OSReleaseMutex(); \ + return RETVAL; \ + } \ + +#define EGL_IF_ERROR(COND, ERRORCODE, RETVAL) \ + if(COND) { eglSetError(egl, ERRORCODE); OSReleaseMutex(); return RETVAL; } \ + +#define EGL_RETURN(ERRORCODE, RETVAL) \ + { \ + eglSetError(egl, ERRORCODE); \ + OSReleaseMutex(); \ + return RETVAL; \ + } + +//#undef EGL_NUMCONFIGS + +#endif /* __RIMINIEGL_H */ + +