diff -r a8e55d78eb52 -r b87045f2f5d7 openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMiniEGL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMiniEGL.h Thu Nov 18 23:28:27 2010 +0000 @@ -0,0 +1,519 @@ +/*------------------------------------------------------------------------ + * + * 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. + *//*-------------------------------------------------------------------*/ +#ifndef __MINI_EGL_H_ +#define __MINI_EGL_H_ + +#include "egl.h" +#include "openvg.h" +#include "riArray.h" +#include "riMath.h" +#include "riContext.h" +#include "riImage.h" + +#include "eglosnativewindowtype.h" + +#ifdef BUILD_WITH_PRIVATE_EGL +#include "eglinternal.h" +#endif + +#ifdef BUILD_WITH_PRIVATE_OPENVG +#include "openvginternal.h" +#endif + +#ifdef EGL_COMPOSITION +// Surface Manager and Update +#include +#include +#include +#include +#include +#include +#include +#endif + + +//============================================================================================== +// EGL header +typedef enum + { + ESurfaceTypeWindow = 0, + ESurfaceTypePbuffer = 1, + ESurfaceTypePixmapFbsBitmap = 2, + ESurfaceTypePixmapSgImage = 3, + } TEglSurfaceType; + +#define KDefaultScreenNumber 0 + +class CEglContext; + +// client side info about a surface +struct TSurfaceInfo + { + //TSurfaceInfo& operator=( TSurfaceInfo& aRhs ); + TSize iSize; + TEglSurfaceType iSurfaceType; //Surface type + EGLConfig iConfigId; + CFbsBitmap* iFbsBitmap; // Handle for CFbsBitmap + + EGLSurface iSurface; // insted of HostSurfaceId + // Note: most member data is only used by Window surfaces + TSurfaceId iSurfaceId; /* iBuffer0, 1 -> iBuffer1 should be display + TNativeWindowType iNativeWindow; // TNativeWindowType used now instead of RWindow directly + TInt iScreenNumber; // either provided by RWindow or default screen(0) + EGLint iRedBits; + EGLint iGreenBits; + EGLint iBlueBits; + EGLint iAlphaBits; + EGLenum iAlphaFormat; + EGLint iColorBits; + EGLint iStride; + // + }; + + +// Container for Symbian client side information about an EGL Display +NONSHARABLE_CLASS(CEglDisplayInfo) : public CBase + { +public: + TBool iInitialized; +// RMutex iSurfaceMapLock; + RHashMap iSurfaceMap; +//private: +// RMutex iContextMapLock; + RHashMap iContextMap; + }; +//============================================================================================== + +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) {} //why VG_sRGBA_8888 and not VG_sARGB_8888 by default? + ~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); + 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; + + // Following functions ported from guestEGL + TBool CreateDisplayInfo(const EGLDisplay aDisplayID); + TBool InitializeDisplayInfo(EGLDisplay aDisplay); + TBool IsDisplayInitialized(EGLDisplay aDisplay); + TBool DestroyDisplayInfo(EGLDisplay aDisplay); + + // API supporting EGL sync extension + EGLint FindAndLockDisplay(EGLDisplay aDisplayID); + void ReleaseDisplayLock(EGLDisplay aDisplayID); + EGLint InitialiseExtensions(); + CEglSyncExtension* EGLSyncExtension() {return iEglSyncExtension;}; + // + TSurfaceInfo& GetSurfaceInfo() {return iSurfaceInfo;}; +// Following should be really private... if there were 'external' equivalents defined in EGL class... +//private: +public: + TBool EglInternalFunction_CreateSurface(EGLDisplay aDisplay, EGLSurface aSurface, EGLConfig aConfig, EGLNativeWindowType aNativeWindow, + TSurfaceInfo& aSurfaceInfo); + TBool EglInternalFunction_CallSetSurfaceParams(EGLDisplay aDisplay, EGLSurface aSurface,TSurfaceInfo& aSurfaceInfo); + TBool EglInternalFunction_SwapBuffers(EGLDisplay aDisplay, EGLSurface aSurface); + TSurfaceInfo* EglInternalFunction_GetPlatformSurface( EGLDisplay display, EGLSurface surface ); + EGLBoolean EglInternalFunction_SurfaceResized(TSurfaceInfo&, int, int); +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; + + //data members supporting EGL Sync extension + CEglSyncExtension* iEglSyncExtension; + TSurfaceInfo iSurfaceInfo; + // public for now +public: + RReadWriteLock iDisplayMapLock; // protects the iDisplayMap for multi-threaded clients + RHashMap iDisplayMap; +}; + +// Note: egl error handling model differs from OpenVG. The latest error is stored instead of the oldest one. +static void eglSetError(EGL* egl, EGLint error); + +EGL* getEGL(); + +/*-------------------------------------------------------------------*//*! +* \brief +* \param +* \return +* \note +*//*-------------------------------------------------------------------*/ + +#define EGL_GET_DISPLAY(DISPLAY, RETVAL) \ + OSAcquireMutex(); \ + EGL* egl = OpenVGRI::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) { OpenVGRI::eglSetError(egl, ERRORCODE); OSReleaseMutex(); return RETVAL; } \ + +#define EGL_RETURN(ERRORCODE, RETVAL) \ + { \ + OpenVGRI::eglSetError(egl, ERRORCODE); \ + OSReleaseMutex(); \ + return RETVAL; \ + } + +/*-------------------------------------------------------------------*//*! +* \brief Returns the OpenVG context current to the calling thread. +* \param +* \return +* \note This function is always called from a mutexed API function +*//*-------------------------------------------------------------------*/ + +void* eglvgGetCurrentVGContext(void); + +/*-------------------------------------------------------------------*//*! +* \brief Check if the image is current in any of the displays +* \param +* \return +* \note This function is always called from a mutexed API function +*//*-------------------------------------------------------------------*/ + +bool eglvgIsInUse(void* image); + + +//============================================================================================== + +} //namespace OpenVGRI + +#endif //__MINI_EGL_H_