/*
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
*/
#include "config.h"
-
-#if ENABLE(TIZEN_WEBKIT2_TILED_AC)
#include "SharedPlatformSurfaceTizen.h"
-#include "PixmapContextTizen.h"
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC)
+#include "EGLHelper.h"
+#include "GLPlatformContext.h"
#include "NotImplemented.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/WTFString.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
#include <stdio.h>
-static PFNEGLLOCKSURFACEKHRPROC eglLockSurfaceKHR = 0;
-static PFNEGLUNLOCKSURFACEKHRPROC eglUnlockSurfaceKHR = 0;
+namespace WebCore {
-static bool vendorNeedsMakeCurrent(const EGLDisplay display)
+static bool vendorNeedsMakeCurrent()
{
static bool queryDone = false;
static bool needsMakeCurrent = true;
if (!queryDone) {
queryDone = true;
- String vendor = eglQueryString(display, EGL_VENDOR);
- Vector<String> vendorComponents;
- vendor.lower().split(' ', vendorComponents);
-
- if (vendorComponents.contains("imagination") || vendorComponents.contains("mesa") || vendorComponents.contains("arm"))
+ if (EGLHelper::isVendor("imagination") || EGLHelper::isVendor("mesa") || EGLHelper::isVendor("arm"))
needsMakeCurrent = false;
}
return needsMakeCurrent;
}
-namespace WebCore {
-
-Display* g_nativeDisplay;
-int g_nativeWindow;
class PixmapContextPool {
protected:
PixmapContextPool(void);
return pixmapContextPool;
}
- PixmapContextTizen* getContext(bool isLockable, bool hasAlpha, bool hasDepth, bool hasStencil);
+ GLPlatformContext* getContext(GLPlatformSurface* surface);
private:
- typedef HashMap<int, RefPtr<PixmapContextTizen> > PixmapContextMap;
+ typedef HashMap<int, OwnPtr<GLPlatformContext> > PixmapContextMap;
PixmapContextMap m_pixmapContexts;
};
PixmapContextPool::PixmapContextPool()
{
- if (!g_nativeDisplay)
- g_nativeDisplay = XOpenDisplay(0);
- if (!g_nativeWindow)
- g_nativeWindow = XCreateSimpleWindow(g_nativeDisplay, XDefaultRootWindow(g_nativeDisplay),
- 0, 0, 1, 1, 0,
- BlackPixel(g_nativeDisplay, 0), WhitePixel(g_nativeDisplay, 0));
- XFlush(g_nativeDisplay);
}
PixmapContextPool::~PixmapContextPool()
{
- PixmapContextMap::iterator end = m_pixmapContexts.end();
- for (PixmapContextMap::iterator iter = m_pixmapContexts.begin(); iter != end; ++iter) {
- RefPtr<PixmapContextTizen> context = iter->second;
- context.release();
- }
m_pixmapContexts.clear();
-
- if (g_nativeWindow) {
- XDestroyWindow(g_nativeDisplay, g_nativeWindow);
- g_nativeWindow = 0;
- }
}
-PixmapContextTizen* PixmapContextPool::getContext(bool isLockable, bool hasAlpha, bool hasDepth, bool hasStencil)
+GLPlatformContext* PixmapContextPool::getContext(GLPlatformSurface* surface)
{
+ GLPlatformSurface::SurfaceAttributes attributes = surface->attributes();
+ bool hasAlpha = attributes & GLPlatformSurface::SupportAlpha;
+ bool hasDepth = attributes & GLPlatformSurface::SupportDepth;
+ bool hasStencil = attributes & GLPlatformSurface::SupportStencil;
+ bool isLockable = attributes & GLPlatformSurface::Lockable;
int contextId = ((isLockable) | (hasAlpha << 1) | (hasDepth << 2) | (hasStencil << 3));
- RefPtr<PixmapContextTizen> pixmapContext = m_pixmapContexts.get(contextId);
- if (!pixmapContext) {
- pixmapContext = PixmapContextTizen::create(isLockable, hasAlpha, hasDepth, hasStencil);
- if (pixmapContext)
- m_pixmapContexts.add(contextId, pixmapContext);
- else
- return 0;
- }
- return pixmapContext.get();
-}
-
-PassRefPtr<PixmapContextTizen> PixmapContextTizen::create(bool isLockable, bool hasAlpha, bool hasDepth, bool hasStencil)
-{
- RefPtr<PixmapContextTizen> context = adoptRef(new PixmapContextTizen(isLockable, hasAlpha, hasDepth, hasStencil));
- if (!context->initialize())
- return 0;
- return context.release();
-}
-
-void PixmapContextTizen::HandleEGLError(const char* name)
-{
- static const char* const egErrorStrings[] =
- {
- "EGL_SUCCESS",
- "EGL_NOT_INITIALIZED",
- "EGL_BAD_ACCESS",
- "EGL_BAD_ALLOC",
- "EGL_BAD_ATTRIBUTE",
- "EGL_BAD_CONFIG",
- "EGL_BAD_CONTEXT",
- "EGL_BAD_CURRENT_SURFACE",
- "EGL_BAD_DISPLAY",
- "EGL_BAD_MATCH",
- "EGL_BAD_NATIVE_PIXMAP",
- "EGL_BAD_NATIVE_WINDOW",
- "EGL_BAD_PARAMETER",
- "EGL_BAD_SURFACE"
- };
-
- EGLint errorCode = eglGetError();
-
- if (errorCode != EGL_SUCCESS)
- TIZEN_LOGE("'%s' returned egl error '%s' (0x%x)", name, egErrorStrings[errorCode - EGL_SUCCESS], errorCode);
-}
-
-PixmapContextTizen::PixmapContextTizen(bool isLockable, bool hasAlpha, bool hasDepth, bool hasStencil)
- : m_initialized(false)
- , m_display(EGL_NO_DISPLAY)
- , m_context(EGL_NO_CONTEXT)
- , m_isLockable(isLockable)
- , m_hasAlpha(hasAlpha)
- , m_hasDepth(hasDepth)
- , m_hasStencil(hasStencil)
-{
-}
-
-PixmapContextTizen::~PixmapContextTizen()
-{
- if (m_context) {
- eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(m_display, m_context);
- m_context = EGL_NO_CONTEXT;
- }
- m_display = 0;
-}
-
-bool PixmapContextTizen::initialize()
-{
- EGLint major, minor;
- EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
- m_display = eglGetDisplay(g_nativeDisplay);
- if (m_display == EGL_NO_DISPLAY)
- HandleEGLError("eglGetDisplay");
-
- if (eglInitialize(m_display, &major, &minor) != EGL_TRUE)
- HandleEGLError("eglInitialize");
-
- EGLint configCount = 0;
- int i = 0;
- EGLint configAttribs[32];
- configAttribs[i++] = EGL_LEVEL;
- configAttribs[i++] = 0;
- // FIXME : Create pixmap surface with RGB_565 when alpha is off. Graphics driver needs to be fixed first.
- configAttribs[i++] = EGL_RED_SIZE;
- configAttribs[i++] = 8;
- configAttribs[i++] = EGL_GREEN_SIZE;
- configAttribs[i++] = 8;
- configAttribs[i++] = EGL_BLUE_SIZE;
- configAttribs[i++] = 8;
- configAttribs[i++] = EGL_ALPHA_SIZE;
- if (m_hasAlpha)
- configAttribs[i++] = 8;
- else {
- configAttribs[i++] = 0;
- configAttribs[i++] = EGL_CONFIG_CAVEAT;
- if (!strcmp(eglQueryString (m_display, EGL_VENDOR), "Imagination Technologies"))
- configAttribs[i++] = EGL_NONE;
- else
- configAttribs[i++] = EGL_NON_CONFORMANT_CONFIG;
- }
-
- if (m_isLockable) {
- configAttribs[i++] = EGL_MATCH_FORMAT_KHR;
- // FIXME : This strcmp will be replaced.to the feature macro.
- if (!strcmp(eglQueryString (m_display, EGL_VENDOR), "ARM"))
- configAttribs[i++] = EGL_FORMAT_RGBA_8888_EXACT_KHR;
- else if (!strcmp(eglQueryString (m_display, EGL_VENDOR), "Imagination Technologies"))
- configAttribs[i++] = EGL_FORMAT_RGBA_8888_EXACT_KHR;
- else
- configAttribs[i++] = EGL_FORMAT_RGBA_8888_KHR;
- configAttribs[i++] = EGL_SURFACE_TYPE;
- configAttribs[i++] = EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR;
- configAttribs[i++] = EGL_DEPTH_SIZE;
- configAttribs[i++] = 0;
- configAttribs[i++] = EGL_STENCIL_SIZE;
- configAttribs[i++] = 0;
- } else {
- configAttribs[i++] = EGL_SURFACE_TYPE;
- configAttribs[i++] = EGL_PIXMAP_BIT;
- configAttribs[i++] = EGL_DEPTH_SIZE;
- if (m_hasDepth)
- configAttribs[i++] = 16;
- else
- configAttribs[i++] = 0;
- configAttribs[i++] = EGL_STENCIL_SIZE;
- if (m_hasStencil)
- configAttribs[i++] = 8;
- else
- configAttribs[i++] = 0;
- }
- configAttribs[i++] = EGL_RENDERABLE_TYPE;
- configAttribs[i++] = EGL_OPENGL_ES2_BIT;
- configAttribs[i++] = EGL_NONE;
-
- if (eglChooseConfig(m_display, configAttribs, &m_surfaceConfig, 1, &configCount) != EGL_TRUE) {
- HandleEGLError("eglChooseConfig");
- return false;
- }
- m_context = eglCreateContext(m_display, m_surfaceConfig, EGL_NO_CONTEXT, contextAttribs);
- if( m_context == EGL_NO_CONTEXT) {
- HandleEGLError("eglCreateContext");
- return false;
- }
- return true;
-}
-
-bool PixmapContextTizen::makeCurrent(EGLSurface surface)
-{
- if (eglGetCurrentSurface(EGL_READ) == surface && eglGetCurrentSurface(EGL_DRAW) == surface && eglGetCurrentContext() == m_context)
- return true;
-
- if (eglMakeCurrent(m_display, surface, surface, m_context) != EGL_TRUE) {
- HandleEGLError("eglMakeCurrent");
- return false;
- }
- return true;
-}
-
-void* PixmapContextTizen::createSurface(int pixmapID)
-{
- EGLSurface surface = eglCreatePixmapSurface(m_display, m_surfaceConfig, pixmapID, NULL);
- if (surface == EGL_NO_SURFACE)
- HandleEGLError("eglCreatePixmapSurface");
+ GLPlatformContext* pixmapContext = m_pixmapContexts.get(contextId);
- return surface;
-}
-
-void PixmapContextTizen::destroySurface(EGLSurface surface)
-{
- if (surface) {
- if (eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE)
- HandleEGLError("eglMakeCurrent");
- eglDestroySurface(m_display, surface);
- }
-}
-
-bool PixmapContextTizen::lockSurface(EGLSurface surface)
-{
- EGLint lockAttrib[] = { EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR, EGL_NONE };
- if (!eglLockSurfaceKHR)
- eglLockSurfaceKHR = (PFNEGLLOCKSURFACEKHRPROC)eglGetProcAddress("eglLockSurfaceKHR");
-
- if (vendorNeedsMakeCurrent(m_display))
- eglMakeCurrent(m_display, surface, surface, m_context);
-
- if (eglLockSurfaceKHR(m_display, surface, lockAttrib) != EGL_TRUE) {
- HandleEGLError("eglLockSurfaceKHR");
- return false;
- }
- return true;
-}
+ if (pixmapContext && !pixmapContext->makeCurrent(surface))
+ pixmapContext = 0;
-bool PixmapContextTizen::unlockSurface(EGLSurface surface)
-{
- if (!eglUnlockSurfaceKHR)
- eglUnlockSurfaceKHR = (PFNEGLUNLOCKSURFACEKHRPROC)eglGetProcAddress("eglUnlockSurfaceKHR");
- if (eglUnlockSurfaceKHR(m_display, surface) != EGL_TRUE) {
- HandleEGLError("eglUnlockSurfaceKHR");
- return false;
- }
- return true;
-}
-
-bool PixmapContextTizen::querySurface(EGLSurface surface, EGLint* value)
-{
- if (eglQuerySurface(m_display, surface, EGL_BITMAP_POINTER_KHR, value) != EGL_TRUE) {
- HandleEGLError("eglQuerySurface");
- return false;
+ if (!pixmapContext) {
+ OwnPtr<GLPlatformContext> context = GLPlatformContext::createContext(GraphicsContext3D::RenderOffscreen);
+ if (context && context->initialize(surface)) {
+ m_pixmapContexts.add(contextId, context.release());
+ pixmapContext = context.get();
+ } else
+ return 0;
}
- return true;
+ return pixmapContext;
}
-int PixmapContextTizen::createPixmap(int width, int height)
+PassOwnPtr<SharedPlatformSurfaceTizen> SharedPlatformSurfaceTizen::create(const IntSize& size, bool lockable, bool hasAlpha, bool hasDepth, bool hasStencil)
{
- // FIXME : Create 16 bit pixmap when alpha is off. Graphics driver needs to be fixed first.
- int pix = XCreatePixmap(g_nativeDisplay, g_nativeWindow, width, height, 32);
- XFlush(g_nativeDisplay);
-
- return pix;
-}
-
-void PixmapContextTizen::freePixmap(int pixmap)
-{
- if (pixmap)
- XFreePixmap(g_nativeDisplay, pixmap);
-}
-
-PassOwnPtr<SharedPlatformSurfaceTizen> SharedPlatformSurfaceTizen::create(const IntSize& size, bool lockable, bool hasAlpha, bool hasDepth, bool hasStencil, PixmapContextTizen* pixmapContext)
-{
- OwnPtr<SharedPlatformSurfaceTizen> pixmap = adoptPtr(new SharedPlatformSurfaceTizen(size, lockable, hasAlpha, hasDepth, hasStencil, pixmapContext));
+ OwnPtr<SharedPlatformSurfaceTizen> pixmap = adoptPtr(new SharedPlatformSurfaceTizen(size, lockable, hasAlpha, hasDepth, hasStencil));
if (!pixmap->initialize())
return nullptr;
return pixmap.release();
}
-// FIXME: This function needs a better place
bool SharedPlatformSurfaceTizen::supportsLockSurfaceExtension()
{
static bool extSupportQueried = false;
static bool supportLockSurfaceExt = false;
if (extSupportQueried)
- return supportLockSurfaceExt;
+ return supportLockSurfaceExt;
extSupportQueried = true;
- Display* nativeDisplay = 0;
- EGLDisplay display = eglGetCurrentDisplay();
-
- if (display == EGL_NO_DISPLAY) {
- nativeDisplay = XOpenDisplay(0);
- display = eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(nativeDisplay));
- eglInitialize(display, 0, 0);
- }
+ EGLDisplay display = EGLHelper::currentDisplay();
- if (display != EGL_NO_DISPLAY) {
- String rawExtensions = reinterpret_cast<const char*>(eglQueryString(display, EGL_EXTENSIONS));
- Vector<String> extNames;
- rawExtensions.lower().split(" ", extNames);
-
- if (extNames.contains("egl_khr_lock_surface"))
- supportLockSurfaceExt = true;
-
- extNames.clear();
- }
+ if (display == EGL_NO_DISPLAY)
+ return false;
+ supportLockSurfaceExt = GLPlatformContext::supportsEGLExtension(display, "EGL_KHR_lock_surface");
return supportLockSurfaceExt;
}
-SharedPlatformSurfaceTizen::SharedPlatformSurfaceTizen(const IntSize& size, bool lockable, bool hasAlpha, bool hasDepth, bool hasStencil, PixmapContextTizen* pixmapContext)
- : m_pixmap(0)
- , m_size(size)
- , m_surface(0)
- , m_isLockable(lockable)
- , m_hasAlpha(hasAlpha)
- , m_hasDepth(hasDepth)
- , m_hasStencil(hasStencil)
+SharedPlatformSurfaceTizen::SharedPlatformSurfaceTizen(const IntSize& size, bool lockable, bool hasAlpha, bool hasDepth, bool hasStencil)
+ : m_size(size)
, m_isUsed(false)
+ , m_offScreenContext(0)
{
- m_pixmapContext = pixmapContext;
+ m_sharedSurfaceAttributes = GLPlatformSurface::Default;
+
+ if (hasAlpha)
+ m_sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha;
+
+ if (lockable)
+ m_sharedSurfaceAttributes = GLPlatformSurface::Lockable;
+ else {
+ if (hasDepth)
+ m_sharedSurfaceAttributes = GLPlatformSurface::SupportDepth;
+
+ if (hasStencil)
+ m_sharedSurfaceAttributes = GLPlatformSurface::SupportStencil;
+ }
}
SharedPlatformSurfaceTizen::~SharedPlatformSurfaceTizen()
{
- if (m_surface != EGL_NO_SURFACE) {
- m_pixmapContext->destroySurface(m_surface);
- m_surface = EGL_NO_SURFACE;
- }
- if (m_pixmap) {
- m_pixmapContext->freePixmap(m_pixmap);
- m_pixmap = 0;
+ if (m_offScreenSurface) {
+ m_offScreenContext->releaseCurrent();
+ m_offScreenSurface->destroy();
}
}
if (m_size.isEmpty())
return false;
- if(!m_pixmapContext) {
- PixmapContextPool& pixmapContextPool = PixmapContextPool::getInstance();
- m_pixmapContext = pixmapContextPool.getContext(m_isLockable, m_hasAlpha, m_hasDepth, m_hasStencil);
- }
+ m_offScreenSurface = GLPlatformSurface::createOffScreenSurface(m_sharedSurfaceAttributes, m_size);
- if(!m_pixmapContext)
+ if (!m_offScreenSurface)
return false;
- m_pixmap = m_pixmapContext->createPixmap(m_size.width(), m_size.height());
- if (!m_pixmap)
- return false;
- m_surface = (void*)(m_pixmapContext->createSurface(m_pixmap));
- if (m_surface == EGL_NO_SURFACE)
+ PixmapContextPool& pixmapContextPool = PixmapContextPool::getInstance();
+ m_offScreenContext = pixmapContextPool.getContext(m_offScreenSurface.get());
+
+ if (!m_offScreenContext) {
+ m_offScreenSurface->destroy();
+ m_offScreenSurface = nullptr;
return false;
+ }
+
return true;
}
void* SharedPlatformSurfaceTizen::context()
{
- return m_pixmapContext->context();
+ return m_offScreenContext ? m_offScreenContext->handle() : 0;
}
bool SharedPlatformSurfaceTizen::makeContextCurrent()
{
- return m_pixmapContext->makeCurrent(m_surface);
+ bool value = m_offScreenContext ? m_offScreenContext->makeCurrent(m_offScreenSurface.get()) : false;
+ return value;
}
bool SharedPlatformSurfaceTizen::lockSurface()
{
- return m_pixmapContext->lockSurface(m_surface);
+ if (vendorNeedsMakeCurrent())
+ makeContextCurrent();
+
+ static EGLint lockAttrib[] = { EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR, EGL_NONE };
+ return EGLHelper::lockSurface(m_offScreenSurface->drawable(), lockAttrib);
}
bool SharedPlatformSurfaceTizen::unlockSurface()
{
- return m_pixmapContext->unlockSurface(m_surface);
+ return EGLHelper::unlockSurface(m_offScreenSurface->drawable());
}
bool SharedPlatformSurfaceTizen::querySurface(int* value)
{
- int value_local;
- bool ret;
-
- ret = m_pixmapContext->querySurface(m_surface, (EGLint*)&value_local);
+ int* value_local;
+ bool ret = EGLHelper::querySurface(m_offScreenSurface->drawable(), EGL_BITMAP_PITCH_KHR, (EGLint*)&value_local);
*value = (int)value_local;
return ret;
}
+
}
#endif // ENABLE(TIZEN_ACCELERATED_COMPOSITING)