diff -r da7c1a80df0d -r d2d6724aef32 holdingarea/libEGL/src/win32/EGLOs.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/holdingarea/libEGL/src/win32/EGLOs.cpp Thu Sep 16 09:43:14 2010 +0100 @@ -0,0 +1,807 @@ +/* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * 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. + * + * Initial Contributors: + * Nokia Corporation - initial contribution. + * + * Contributors: + * + * Description: + * + */ + +#include "EGLOs.h" +#include "EGLState.h" +#include "EGLProcess.h" +#include "EGLThread.h" +#include "EGLWindowSurface.h" +#include "EGLDisplay.h" +#include "EGLContext.h" + +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) +void doBlit( EGLIOsWindowContext* context, void* buf, int width, int height, int stride ) + { + if( !context->osBuffer || !context->pixmap || context->width != width || context->height != height ) + { + if( context->pixmap ) + DeleteObject( context->pixmap ); + context->osBuffer = NULL; + context->pixmap = NULL; + + context->width = width; + context->height = height; + + struct + { + BITMAPINFOHEADER header; + DWORD rMask; + DWORD gMask; + DWORD bMask; + } bmi; + bmi.header.biSize = sizeof( BITMAPINFOHEADER ); + bmi.header.biWidth = width; + bmi.header.biHeight = height; + bmi.header.biPlanes = 1; + bmi.header.biBitCount = (WORD)32; + bmi.header.biCompression = BI_BITFIELDS; + bmi.rMask = 0x00FF0000; + bmi.gMask = 0x0000FF00; + bmi.bMask = 0x000000FF; + + context->pixmap = CreateDIBSection( context->vgDisplay, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&context->osBuffer, NULL, 0 ); + if( !context->pixmap ) + { + context->osBuffer = NULL; + return; + } + } + + if( context->osBuffer ) + { + HDC winDC = GetDC( context->window ); + GdiFlush(); + memcpy( context->osBuffer, buf, stride*height ); + SelectObject( context->vgDisplay, context->pixmap ); + EGLI_ASSERT( BitBlt(winDC, 0, 0, width, height, context->vgDisplay, 0, 0, SRCCOPY) ); + ReleaseDC( context->window, winDC ); + SelectObject( context->vgDisplay, NULL ); + } + } +#endif + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CLOSE: + case WM_DESTROY: + //PostQuitMessage(0); + return 0; + case WM_PAINT: + { + /*CEGLState* state = getState(); + if( state ) + { + CEGLThread* thread = state->GetCurrentProcess()->CurrentThread(); + if( thread && thread->CurrentVGSurface() ) + { + if( thread->CurrentVGSurface()->Type() == CEGLSurface::WINDOW_SURFACE ) + { + CEGLWindowSurface* surface = (CEGLWindowSurface*)thread->CurrentVGSurface(); + InvalidateRect(hwnd, NULL, 0); + doBlit( surface->OsContext(), surface->VGColorBuffer(), surface->Width(), surface->Height(), surface->Stride() ); + } + } + }*/ + return 0; + } + default: + break; + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +void CEGLOs::InitializeLock( EGLI_LOCK *lock ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + InitializeCriticalSection( lock ); +#endif + } + +void CEGLOs::GetLock( EGLI_LOCK *lock ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + EnterCriticalSection( lock ); +#endif + } + +void CEGLOs::ReleaseLock(EGLI_LOCK *lock ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + LeaveCriticalSection( lock ); +#endif + } + +void CEGLOs::DestroyLock( EGLI_LOCK *lock ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + DeleteCriticalSection( lock ); +#endif + } + +void CEGLOs::ConfigToNativePixelFormat( const CEGLConfig& config, EGLINativePixelFormatType* nativeFormat ) + { + EGLI_ASSERT( nativeFormat != NULL ); + memset( nativeFormat, 0, sizeof(PIXELFORMATDESCRIPTOR) ); + nativeFormat->nSize = sizeof( PIXELFORMATDESCRIPTOR ); + nativeFormat->nVersion = 1; + nativeFormat->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; // always support OGL + + // \todo Do we need color index? + nativeFormat->iPixelType = PFD_TYPE_RGBA; + + // \todo overlay/underlay? + nativeFormat->iLayerType = PFD_MAIN_PLANE; + + EGLint surfaceType = config.GetAttribute( EGL_SURFACE_TYPE ); + if( surfaceType & EGL_WINDOW_BIT ) + { + nativeFormat->dwFlags |= PFD_DRAW_TO_WINDOW; + } + if( surfaceType & EGL_PIXMAP_BIT ) + { + nativeFormat->dwFlags |= PFD_DRAW_TO_BITMAP; + } + nativeFormat->cColorBits = config.GetAttribute( EGL_RED_SIZE ) + + config.GetAttribute( EGL_GREEN_SIZE ) + + config.GetAttribute( EGL_BLUE_SIZE ); + + nativeFormat->cAlphaBits = config.GetAttribute( EGL_ALPHA_SIZE ); + nativeFormat->cDepthBits = config.GetAttribute( EGL_DEPTH_SIZE ); + nativeFormat->cStencilBits = config.GetAttribute( EGL_STENCIL_SIZE ); + + // \todo Aux buffers, accumulation buffers? + } + +EGLINativeContextType CEGLOs::CreateNativeContext( const CEGLConfig& config, EGLINativeDisplayType display, EGLINativeContextType shareContext ) + { + EGLINativeContextType ret = NULL; + DWORD error = ERROR_SUCCESS; +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + CEGLOs::ConfigToNativePixelFormat( config, &pfd ); + int pixelFormat = ChoosePixelFormat( display, &pfd ); + if( !pixelFormat ) + { + return ret; + } + int currentPixelFormat = GetPixelFormat( display ); + if( !currentPixelFormat && !SetPixelFormat( display, pixelFormat, &pfd ) ) + { + error = GetLastError(); + return ret; + } + ret = wglCreateContext( display ); + if( ret != NULL && shareContext != NULL) + { + // Share context data + if( !wglShareLists( shareContext, ret ) ) + { + wglDeleteContext( ret ); + ret = NULL; + } + } +#endif + return ret; + } + +EGLINativeContextType CEGLOs::CurrentNativeContext() + { + return wglGetCurrentContext(); + } + +EGLINativeDisplayType CEGLOs::CurrentNativeSurface() + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + return wglGetCurrentDC(); +#else + return NULL; +#endif + } + +bool CEGLOs::MakeNativeContextCurrent( struct EGLINativeGLFunctions* func, EGLINativeDisplayType draw, EGLINativeDisplayType read, EGLINativeContextType context ) + { + bool ret = true; +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + DWORD err; + EGLINativeContextType prevContext = wglGetCurrentContext(); + EGLINativeDisplayType prevDraw = wglGetCurrentDC(); + EGLINativeDisplayType prevRead = NULL; + if( prevDraw ) prevRead = func->wglGetCurrentReadDCARB(); + if( context == NULL ) + { + if( wglGetCurrentContext() != NULL ) + { + //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) + ret = (wglMakeCurrent( NULL, context ) != 0); + } + } + else + { + //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) + ret = (func->wglMakeContextCurrentARB( draw, read, context ) != 0); + } + if( !ret ) + { + // \todo Handle error + err = GetLastError(); + // Restore previous context/surface on failure + func->wglMakeContextCurrentARB( prevDraw, prevRead, prevContext ); + } +#endif + return ret; + } + +bool CEGLOs::DestroyNativeContext( EGLINativeContextType context ) + { + bool ret = true; +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + if( context != NULL ) + { + //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) + ret = (wglDeleteContext( context ) != 0); + } +#endif + return ret; + } + +bool CEGLOs::InitializeNativeGLFunctions( struct EGLINativeGLFunctions* func, EGLINativeDisplayType display, EGLINativeContextType context ) + { + bool ret = true; + DWORD error = ERROR_SUCCESS; +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + HDC currentDC = wglGetCurrentDC(); + HGLRC currentContext = wglGetCurrentContext(); + + ret = !!wglMakeCurrent( display, context ); + if( ret ) + { + func->wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetProcAddress( "wglMakeContextCurrentARB" ); + func->wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)wglGetProcAddress ( "wglGetCurrentReadDCARB" ); + func->wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress( "wglChoosePixelFormatARB" ); + func->wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress( "wglCreatePbufferARB" ); + func->wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress( "wglDestroyPbufferARB" ); + func->wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress( "wglGetPbufferDCARB" ); + func->wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress( "wglReleasePbufferDCARB" ); + func->wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress( "wglQueryPbufferARB" ); + + if( !(func->wglChoosePixelFormatARB && + func->wglCreatePbufferARB && + func->wglDestroyPbufferARB && + func->wglGetPbufferDCARB && + func->wglMakeContextCurrentARB && + func->wglGetCurrentReadDCARB && + func->wglQueryPbufferARB && + func->wglReleasePbufferDCARB) ) + ret = false; + } + + // \todo Other needed extensions. + + if( !(wglMakeCurrent( currentDC, currentContext )) ) + { + error = GetLastError(); + if( error == ERROR_INVALID_HANDLE ) + { + // For some reason the current DC or current wgl context was invalid. + // Just set them NULL for now. + wglMakeCurrent(NULL, NULL); + } + else + { + ret = false; + } + } +#endif //EGLI_USE_PLATSIM_EXTENSIONS + return ret; + } + +struct EGLINativePbufferContainer* CEGLOs::CreateNativePbuffer( EGLINativeDisplayType display, + const CEGLConfig& config, EGLint width, EGLint height, EGLBoolean largestPbuffer, + EGLint textureFormat, EGLint textureTarget ) + { + struct EGLINativePbufferContainer* ret = EGLI_NEW EGLINativePbufferContainer; + if( !ret ) return NULL; + memset( ret, 0, sizeof(struct EGLINativePbufferContainer) ); +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + EGLINativeContextType context = CEGLOs::CreateNativeContext( config, display, NULL ); + if( !context ) + { + delete ret; + ret = NULL; + return ret; + } + ret->copyContext = context; + if( !(CEGLOs::InitializeNativeGLFunctions( &(ret->functions), display, ret->copyContext )) ) + { + CEGLOs::DestroyNativePbuffer( ret ); + delete ret; + ret = NULL; + return ret; + } + + int redSize = config.GetAttribute( EGL_RED_SIZE ); + int greenSize = config.GetAttribute( EGL_GREEN_SIZE ); + int blueSize = config.GetAttribute( EGL_BLUE_SIZE ); + int alphaSize = config.GetAttribute( EGL_ALPHA_SIZE ); + int depthSize = config.GetAttribute( EGL_DEPTH_SIZE ); + int stencilSize = config.GetAttribute( EGL_STENCIL_SIZE ); + + // \todo Map EGL config properly to WGL config. + int attributes[] = + { + WGL_SUPPORT_OPENGL_ARB, TRUE, + WGL_DRAW_TO_PBUFFER_ARB, TRUE, + WGL_RED_BITS_ARB, redSize, + WGL_GREEN_BITS_ARB, greenSize, + WGL_BLUE_BITS_ARB, blueSize, + WGL_ALPHA_BITS_ARB, alphaSize, + WGL_DEPTH_BITS_ARB, depthSize, + WGL_STENCIL_BITS_ARB, stencilSize, + WGL_DOUBLE_BUFFER_ARB, TRUE, + 0 + }; + unsigned int formatCount = 0; + int pixelFormat = 0; + if( !(ret->functions.wglChoosePixelFormatARB( display, attributes, NULL, 1, &pixelFormat, &formatCount )) ) + { + EGLI_ASSERT(false); + DWORD err = GetLastError(); + CEGLOs::DestroyNativePbuffer( ret ); + delete ret; + ret = NULL; + return ret; + } + if( formatCount == 0 ) + { + EGLI_ASSERT(false); + DWORD err = GetLastError(); + CEGLOs::DestroyNativePbuffer( ret ); + delete ret; + ret = NULL; + return ret; + } + int wglTextureFormat = WGL_NO_TEXTURE_ARB; + switch( textureFormat ) + { + case EGL_TEXTURE_RGB: + { + wglTextureFormat = WGL_TEXTURE_RGB_ARB; + break; + } + case EGL_TEXTURE_RGBA: + { + wglTextureFormat = WGL_TEXTURE_RGBA_ARB; + break; + } + } + int wglTextureTarget = WGL_NO_TEXTURE_ARB; + switch( textureTarget ) + { + case EGL_TEXTURE_2D: + { + wglTextureTarget = WGL_TEXTURE_2D_ARB; + break; + } + } + int pbufferAttributes[] = + { + WGL_TEXTURE_FORMAT_ARB, wglTextureFormat, + WGL_TEXTURE_TARGET_ARB, wglTextureTarget, + WGL_PBUFFER_LARGEST_ARB, largestPbuffer, + 0 + }; + ret->pbuffer = ret->functions.wglCreatePbufferARB( display, pixelFormat, + width, height, pbufferAttributes ); + if( !(ret->pbuffer) ) + { + EGLI_ASSERT(false); + DWORD err = GetLastError(); + CEGLOs::DestroyNativePbuffer( ret ); + delete ret; + ret = NULL; + return ret; + } + ret->display = ret->functions.wglGetPbufferDCARB( ret->pbuffer ); + if( !(ret->display) ) + { + EGLI_ASSERT(false); + DWORD err = GetLastError(); + CEGLOs::DestroyNativePbuffer( ret ); + delete ret; + ret = NULL; + return ret; + } +#endif // EGLI_USE_PLATSIM_EXTENSIONS + return ret; + } + +bool CEGLOs::DestroyNativePbuffer( struct EGLINativePbufferContainer* container ) + { + // \todo Handle errors! + bool ret = true; +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + DWORD err; + if( container->display && container->pbuffer && container->functions.wglReleasePbufferDCARB ) + { + if( !(container->functions.wglReleasePbufferDCARB(container->pbuffer, container->display)) ) + { + err = GetLastError(); + ret = false; + } + } + if( container->pbuffer && container->functions.wglDestroyPbufferARB ) + { + if( !(container->functions.wglDestroyPbufferARB(container->pbuffer)) ) + { + err = GetLastError(); + ret = false; + } + } + if( container->copyContext ) + { + ret = CEGLOs::DestroyNativeContext( container->copyContext ); + if( !ret ) + { + err = GetLastError(); + } + } +#endif //EGLI_USE_PLATSIM_EXTENSIONS + return ret; + } + +EGLINativeDisplayType CEGLOs::CreateDefaultDisplay() + { + // \todo It seems that we can't use any of these DC-functions. + // Problems with pixel format selection etc. at least with + // NVidia and Intel GPUs, ATI/AMD seems to work with GetDC(NULL) + // or CreateDC(). No idea how to create EGL_DEFAULT_DISPLAY for + // NV/Intel GPUs. For now CEGLDisplay::Initialize() creates dummy + // window and uses DC from that window. + //return (EGLINativeDisplayType)CreateDC(TEXT("DISPLAY"), TEXT("DISPLAY")/*NULL*/, NULL, NULL); + //return (EGLINativeDisplayType)GetDC(NULL); + //return GetWindowDC(NULL); + return NULL; + } + +void CEGLOs::DestroyDefaultDisplay( EGLINativeDisplayType display ) + { +#if defined(EGLI_USE_PLATSIM_EXTENSIONS) + // no-op +#else + DeleteDC( display ); +#endif + } + +EGLINativeWindowType CEGLOs::CreateNativeWindow( int width, int height ) + { + int xBorder = GetSystemMetrics( SM_CXBORDER ); + int yBorder = GetSystemMetrics( SM_CYBORDER ); + int caption = GetSystemMetrics( SM_CYCAPTION ); + + + WNDCLASS wndclass; + wndclass.style = 0; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = (HINSTANCE)GetModuleHandle(NULL); + wndclass.hIcon = LoadIcon(wndclass.hInstance, MAKEINTRESOURCE(101)); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = "EGLMainWndClass"; + if (!wndclass.hIcon) + wndclass.hIcon = LoadIcon(NULL, IDI_EXCLAMATION); + + // \todo We should store this class somewhere + RegisterClass(&wndclass); + + EGLINativeWindowType window = CreateWindow( + "EGLMainWndClass", + "Platsim EGL window", + WS_OVERLAPPEDWINDOW, + 0, 0, + width /*+ 2*xBorder*/, + height /*+ 2*yBorder + caption*/, + NULL, + NULL, + (HINSTANCE)GetModuleHandle(NULL), + NULL); + return window; + } + +void CEGLOs::DestroyNativeWindow( EGLINativeWindowType wnd ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + if( wnd ) + EGLI_ASSERT( DestroyWindow( wnd ) ); + // \todo Should use stored WNDCLASS to unregister, see CEGLOs::CreateNativeWindow() + UnregisterClass( "EGLMainWndClass", (HINSTANCE)GetModuleHandle(NULL) ); +#endif + } + +bool CEGLOs::IsValidNativeDisplay( EGLINativeDisplayType dsp ) + { +#if defined(EGLI_USE_PLATSIM_EXTENSIONS) + // we can't validate symbian display + return true; +#else + // Check if we have invalid handle or handle is not display + bool ret = true; + DWORD err = GetLastError(); + SetLastError( ERROR_SUCCESS ); + int technology = GetDeviceCaps( dsp, TECHNOLOGY ); + if( GetLastError() == ERROR_INVALID_HANDLE || technology != DT_RASDISPLAY ) + { + ret = false; + } + SetLastError( err ); + return ret; +#endif + } + +bool CEGLOs::IsValidNativeWindow( EGLINativeWindowType wnd ) + { +#if defined(EGLI_USE_PLATSIM_EXTENSIONS) + // We can't validate symbian window + return true; +#else + bool ret = false; + if( wnd ) + { + // \todo should we skip thread id check? + DWORD processId = GetCurrentProcessId(); + DWORD threadId = GetCurrentThreadId(); + DWORD windowProcessId; + DWORD windowThreadId = GetWindowThreadProcessId( wnd, &windowProcessId ); + ret = ((threadId == windowThreadId) && (processId == windowProcessId)); + } + return ret; +#endif //EGLI_USE_PLATSIM_EXTENSIONS + } + +bool CEGLOs::GetNativeWindowSize( EGLINativeWindowType wnd, int& width, int& height ) + { +#if defined( EGLI_USE_PLATSIM_EXTENSIONS ) + // Window size is transferred through eglPlatsimSetSurfaceParameters() + return true; + +#else + bool ret = false; + RECT rect; + ret = !!GetClientRect( wnd, &rect ); + if( ret ) + { + width = rect.right - rect.left; + height = rect.bottom - rect.top; + } + return ret; +#endif + } + +EGLIOsWindowContext* CEGLOs::CreateOSWindowContext( EGLINativeWindowType wnd, const CEGLConfig& config ) + { + EGLIOsWindowContext* ctx = NULL; + ctx = EGLI_NEW EGLIOsWindowContext; + if( !ctx ) + { + return NULL; + } + ctx->window = wnd; + ctx->vgDisplay = NULL; + ctx->glesDisplay = NULL; + ctx->pixmap = NULL; + ctx->osBuffer = NULL; + ctx->width = 0; + ctx->height = 0; + ctx->colorBuf = NULL; +#if defined(EGLI_USE_PLATSIM_EXTENSIONS) + // no-op +#else + if( ctx->window ) + { + EGLint renderableType = config.GetAttribute( EGL_RENDERABLE_TYPE ); + if( renderableType & EGL_OPENVG_BIT ) + { + HDC winDC = GetDC(ctx->window); + ctx->vgDisplay = CreateCompatibleDC(winDC); + ReleaseDC(ctx->window, winDC); + if(!ctx->vgDisplay) + { + delete ctx; + return NULL; + } + } + if( renderableType & EGL_OPENGL_ES_BIT ) + { + HDC winDC = GetDC(ctx->window); + ctx->glesDisplay = winDC; + if(!ctx->glesDisplay) + { + delete ctx; + return NULL; + } + PIXELFORMATDESCRIPTOR pfd; + CEGLOs::ConfigToNativePixelFormat( config, &pfd ); + + int pixelFormat = ChoosePixelFormat( ctx->glesDisplay, &pfd ); + if( !pixelFormat ) + { + EGLI_ASSERT( false ); + } + if( !SetPixelFormat(ctx->glesDisplay, pixelFormat, &pfd ) ) + { + EGLI_ASSERT( false ); + } + } + } +#endif + return ctx; + } + +void CEGLOs::DestroyOSWindowContext( EGLIOsWindowContext* context ) + { +#if !defined(EGLI_USE_PLATSIM_EXTENSIONS) + if(!context->vgDisplay) + { + SelectObject(context->vgDisplay, NULL); + DeleteDC(context->vgDisplay); + } + if( context->glesDisplay ) + { + ReleaseDC( context->window, context->glesDisplay ); + } + if( context->pixmap ) + DeleteObject( context->pixmap ); + if( context->colorBuf ) + free( context->colorBuf ); + delete context; +#else + delete context; +#endif + } + +void CEGLOs::BlitToOSWindow( EGLenum api, CEGLDisplay* display, EGLIOsWindowContext* context, void* buf, int width, int height, int stride ) + { +#if defined(EGLI_USE_PLATSIM_EXTENSIONS) + // \todo GLES + CEGLState* state = getState(); + if( !state ) + return; + CEGLThread* thread = state->GetCurrentProcess()->CurrentThread(); + switch( api ) + { + case EGL_OPENVG_API: + { + if( thread && state->VGInterface() ) + { + if( thread->CurrentVGSurface() ) + { + CEGLSurface* surface = thread->CurrentVGSurface(); + EGLI_ASSERT( surface->Type() == CEGLSurface::WINDOW_SURFACE ); + state->VGInterface()->CopyBuffers( buf, -stride, surface->VGClientSurface() ); + } + } + break; + } + case EGL_OPENGL_ES_API: + { + if (state->GLESInterface(thread->CurrentGLESContext()->ClientVersion())) + { + // \todo + } + break; + } + } +#else + if( api == EGL_OPENGL_ES_API ) + { + SwapBuffers( context->glesDisplay ); + } + else + { + doBlit(context, buf, width, height, stride); + } +#endif + } + +EGLILibraryHandle CEGLOs::LoadHostGL() + { + return LoadLibrary( TEXT("opengl32.dll") ); + } + +void* CEGLOs::GetGLProcAddress(EGLILibraryHandle& libraryHandle, const char* proc) + { + void* addr = GetProcAddress(libraryHandle, proc); + if(!addr) + { + addr = wglGetProcAddress(proc); + } + + return addr; + } + +bool CEGLOs::FreeClientLibrary(EGLILibraryHandle& libraryHandle) + { + // != 0 added to expression below because of + // warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) + return (FreeLibrary( libraryHandle ) != 0); + } + +IEGLtoVGInterface* CEGLOs::LoadVGInterface( EGLILibraryHandle& libraryHandle ) + { + IEGLtoVGInterface* iFace = NULL; + fpGetVGInterface proc; + libraryHandle = LoadLibrary( TEXT("libOpenVG.dll") ); + if( libraryHandle != NULL ) + { + proc = (fpGetVGInterface)GetProcAddress( libraryHandle, "getVGInterface" ); + if( proc != NULL ) + { + iFace = proc(); + } + } + return iFace; + } + +IEGLtoGLESInterface* CEGLOs::LoadGLES1Interface( EGLILibraryHandle& libraryHandle ) + { + IEGLtoGLESInterface* iFace = NULL; + fpGetGLES1Interface proc; + libraryHandle = LoadLibrary( TEXT("libGLESv1.dll") ); + if( libraryHandle != NULL ) + { + proc = (fpGetGLES1Interface)GetProcAddress( libraryHandle, "getGLESInterface" ); + if( proc != NULL ) + { + iFace = proc(); + } + } + return iFace; + } + +IEGLtoGLES2Interface* CEGLOs::LoadGLES2Interface( EGLILibraryHandle& libraryHandle ) + { + IEGLtoGLES2Interface* iFace = NULL; + fpGetGLES2Interface proc; + libraryHandle = LoadLibrary( TEXT("libGLESv2.dll") ); + if( libraryHandle != NULL ) + { + proc = (fpGetGLES2Interface)GetProcAddress( libraryHandle, "getGLES2Interface" ); + if( proc != NULL ) + { + iFace = proc(); + } + } + return iFace; + }