Support for sharing wl_buffers between Web and UI process. 37/7737/7
authorKondapally Kalyan <kalyan.kondapally@intel.com>
Mon, 5 Aug 2013 05:35:02 +0000 (08:35 +0300)
committerKondapally Kalyan <kalyan.kondapally@intel.com>
Mon, 5 Aug 2013 05:35:02 +0000 (08:35 +0300)
This patch adds support for sharing wl_buffers between UI and
WebProcess. The patch also makes necessary adoptation in the
platform layer of GraphicsContext3D.

Change-Id: I2ee281022c6ec2c856a7bc08392a37c22b0d3efa

29 files changed:
Source/WTF/wtf/Platform.h
Source/WebCore/PlatformTizen.cmake
Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.h [new file with mode: 0644]
Source/WebCore/platform/graphics/efl/tizen/GraphicsContext3DInternal.cpp
Source/WebCore/platform/graphics/efl/tizen/GraphicsContext3DInternal.h
Source/WebCore/platform/graphics/efl/tizen/TizenGraphicsContext3DEfl.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLConfigSelector.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLContext.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLHelper.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLHelper.h
Source/WebCore/platform/graphics/surfaces/egl/EGLWaylandSurface.cpp
Source/WebCore/platform/graphics/surfaces/egl/EGLWaylandSurface.h
Source/WebCore/platform/graphics/surfaces/wayland/GraphicsSurfaceWayland.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandHelper.cpp [deleted file]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandHelper.h
Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.h [new file with mode: 0644]
Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
Source/WebKit2/PlatformTizen.cmake
Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp

index 864d7f4..4711cd2 100644 (file)
@@ -725,10 +725,17 @@ com) : Patch to do not adjust cover rect as fixed pixel size*/
 #define ENABLE_TIZEN_2D_CANVAS_JS_SUSPEND 0 /* Hyunki Baik(hyunki.baik@samsung.com):  Suspend JavasScript during UIProcess access the shared platformSurface for 2D Canvas */
 #endif
 
+#if !USE(MESA)
+#define ENABLE_TIZEN_DDK_WORKAROUND 1 /* kalyan.kondapally@intel.com  WorkAround in AcceleratedPlatformLayer for ddk issues*/
+#endif
+
 #if ENABLE(TIZEN_WEBKIT2)
 #define ENABLE_TIZEN_MOBILE_WEB_PRINT 1 /* Hyunsoo Shim(hyunsoo.shim@samsung.com) : Mobile Web Print for AC layer */
 #endif
 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
+#if PLATFORM(WAYLAND)
+#define ENABLE_TIZEN_ACCELERATED_PLATFORM_LAYER 1 /* Kalyan Kondapally(kalyan.kondapally@intel.com) : GraphicsPlatformLayer used with Wayland. */
+#endif
 #define ENABLE_TIZEN_ACCELERATED_COMPOSITING_PLUGIN_LAYER_EFL 1 /* Hyunsoo Shim(hyunsoo.shim@samsung.com) : Accelerated Compositing plugin layer */
 #if ENABLE(REQUEST_ANIMATION_FRAME)
 #define ENABLE_TIZEN_SYNC_REQUEST_ANIMATION_FRAME 1 /* YongGeol Jung(yg48.jung@samsung.com) : Synchronize callback function of ScriptedAnimationController between UI Process and Web Process to 1 : 1 */
index 39a3af0..e2b10d2 100755 (executable)
@@ -161,7 +161,6 @@ LIST(APPEND WebCore_SOURCES
     platform/graphics/efl/tizen/Extensions3DTizen.cpp
     platform/graphics/efl/tizen/GraphicsContext3D.cpp
     platform/graphics/efl/tizen/GraphicsContext3DInternal.cpp
-    platform/graphics/efl/tizen/GraphicsContext3DOffscreen.cpp
     platform/graphics/efl/tizen/SharedPlatformSurfaceTizen.cpp
     platform/graphics/efl/tizen/TizenGraphicsContext3DEfl.cpp
     platform/graphics/gpu/DrawingBuffer.cpp
@@ -170,8 +169,6 @@ LIST(APPEND WebCore_SOURCES
     platform/graphics/gstreamer/tizen/VideoLayerTizen.cpp
     platform/graphics/gstreamer/tizen/WebKitCameraSourceGStreamerTizen.cpp
     platform/graphics/surfaces/GraphicsSurface.cpp
-    platform/graphics/surfaces/tizen/GraphicsSurfaceTizen.cpp
-    platform/graphics/texmap/tizen/PlatformSurfaceTextureGL.cpp
 
     platform/mediastream/tizen/LocalMediaServer.cpp
     platform/mediastream/tizen/MediaRecorder.cpp
@@ -223,14 +220,22 @@ IF (WTF_USE_ACCELERATED_COMPOSITING AND ENABLE_WEBKIT2)
 
     IF (WTF_PLATFORM_X11)
         LIST(APPEND WebCore_SOURCES
+            platform/graphics/efl/tizen/GraphicsContext3DOffscreen.cpp
             platform/graphics/surfaces/x/X11Helper.cpp
             platform/graphics/surfaces/egl/EGLXSurface.cpp
             platform/graphics/surfaces/tizen/SharedVideoPlatformSurfaceTizenX.cpp
+            platform/graphics/surfaces/tizen/GraphicsSurfaceTizen.cpp
+            platform/graphics/texmap/tizen/PlatformSurfaceTextureGL.cpp
         )
     ELSEIF (WTF_PLATFORM_WAYLAND)
         LIST(APPEND WebCore_SOURCES
+            platform/graphics/efl/tizen/AcceleratedPlatformLayer.cpp
             platform/graphics/surfaces/egl/EGLWaylandSurface.cpp
-            platform/graphics/surfaces/wayland/WaylandHelper.cpp
+            platform/graphics/surfaces/wayland/PlatformTextureWayland.cpp
+            platform/graphics/surfaces/wayland/WaylandCompositor.cpp
+            platform/graphics/surfaces/wayland/WaylandDisplay.cpp
+            platform/graphics/surfaces/wayland/WaylandSurface.cpp
+            platform/graphics/surfaces/wayland/GraphicsSurfaceWayland.cpp
         )
     ENDIF()
 ENDIF()
diff --git a/Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.cpp b/Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.cpp
new file mode 100644 (file)
index 0000000..3f0a525
--- /dev/null
@@ -0,0 +1,969 @@
+/*
+    Copyright (C) 2011 Samsung Electronics
+    Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "AcceleratedPlatformLayer.h"
+
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+
+#if ENABLE(TIZEN_DDK_WORKAROUND)
+#include "Extensions3D.h"
+#endif
+
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "NotImplemented.h"
+
+#define GL_GLEXT_PROTOTYPES 1
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#ifndef GLchar
+#define GLchar char
+#endif
+
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<AcceleratedPlatformLayer> AcceleratedPlatformLayer::create(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
+{
+    if (renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow)
+        return nullptr;
+
+    OwnPtr<AcceleratedPlatformLayer> internal = adoptPtr(new AcceleratedPlatformLayer(attrs, renderStyle));
+    if (!internal->initialize(0))
+        return nullptr;
+
+    return internal.release();
+}
+
+State::State()
+    : activeTexture(GraphicsContext3D::TEXTURE0)
+    , boundFBO(0)
+    , boundTexture0(0)
+    , sourceFactor(GraphicsContext3D::ONE)
+    , destinationFactor(GraphicsContext3D::ZERO)
+    , depthMask(true)
+    , scissorX(0)
+    , scissorY(0)
+    , scissorWidth(0)
+    , scissorHeight(0)
+    , stencilFunc(GraphicsContext3D::ALWAYS)
+    , stencilRef(0)
+    , stencilMask(UINT_MAX)
+    , stencilFail(GraphicsContext3D::KEEP)
+    , stencilZFail(GraphicsContext3D::KEEP)
+    , stencilZPass(GraphicsContext3D::KEEP)
+    , viewportX(0)
+    , viewportY(0)
+    , viewportWidth(0)
+    , viewportHeight(0)
+{
+    m_state = BlendFuncCacheDirty | DepthMaskCacheDirty | StencilFuncCacheDirty | StencilOpCacheDirty | ViewportCacheDirty;
+}
+
+State::~State()
+{
+    if (!pixelStoreIntMap.isEmpty())
+        pixelStoreIntMap.clear();
+
+    if (!capabilityStateMap.isEmpty())
+        capabilityStateMap.clear();
+}
+
+AcceleratedPlatformLayer::AcceleratedPlatformLayer(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
+    : GraphicsContext3DInternal(attrs, GraphicsContext3D::RenderOffscreen)
+    , m_compositorTexture(0)
+    , m_layerComposited(false)
+    , m_swapBuffers(true)
+    , m_width(1)
+    , m_height(1)
+    , m_surfaceFlags(0)
+    , m_surfaceHandle(0)
+    , m_renderStyle(renderStyle)
+    , m_state(adoptPtr(new State()))
+{
+}
+
+AcceleratedPlatformLayer::~AcceleratedPlatformLayer()
+{
+    if (m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0));
+    GL_CMD(glBindTexture(GL_TEXTURE_2D, 0));
+
+    if (m_compositorTexture)
+        GL_CMD(glDeleteTextures(1, &m_compositorTexture));
+
+    releaseResources();
+}
+
+void AcceleratedPlatformLayer::releaseResources()
+{
+    // Release the current context and drawable only after destroying any associated gl resources.
+    m_surfaceHandle = 0;
+    if (m_offScreenSurface)
+        m_offScreenSurface->destroy();
+
+    if (m_offScreenContext) {
+        m_offScreenContext->destroy();
+        m_offScreenContext->releaseCurrent();
+    }
+}
+
+PlatformLayer* AcceleratedPlatformLayer::platformLayer() const
+{
+    return const_cast<TextureMapperPlatformLayer*>(static_cast<const TextureMapperPlatformLayer*>(this));
+}
+
+bool AcceleratedPlatformLayer::initialize(HostWindow*)
+{
+    if (!initializeSurface())
+        return false;
+
+    validateAttributes();
+
+    // ANGLE integration starts
+    ShBuiltInResources ANGLEResources;
+    ShInitBuiltInResources(&ANGLEResources);
+
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits));
+    GL_CMD(getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors));
+
+    // Always set to 1 for OpenGL ES.
+    ANGLEResources.MaxDrawBuffers = 1;
+    m_compiler.setResources(ANGLEResources);
+    // ANGLE Integration block ENDs
+
+    if (m_renderStyle != GraphicsContext3D::RenderToCurrentGLContext)
+        GL_CMD(glClearColor(0.0, 0.0, 0.0, 0.0));
+
+    return true;
+}
+
+bool AcceleratedPlatformLayer::initializeSurface()
+{
+    m_offScreenContext = GLPlatformContext::createContext(m_renderStyle);
+    if (!m_offScreenContext)
+        return false;
+
+    if (m_renderStyle == GraphicsContext3D::RenderOffscreen) {
+        GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatformSurface::Default;
+        if (m_attributes.alpha)
+            sharedSurfaceAttributes |= GLPlatformSurface::SupportAlpha;
+
+        if (m_attributes.depth)
+            sharedSurfaceAttributes |= GLPlatformSurface::SupportDepth;
+
+        if (m_attributes.stencil)
+            sharedSurfaceAttributes |= GLPlatformSurface::SupportStencil;
+
+        m_offScreenSurface = GLPlatformSurface::createOffScreenSurface(sharedSurfaceAttributes, IntSize(m_width, m_height));
+
+        if (!m_offScreenSurface)
+            return false;
+
+        if (!m_offScreenContext->initialize(m_offScreenSurface.get()))
+            return false;
+
+        if (!makeContextCurrent())
+            return false;
+
+        if (m_offScreenSurface->attributes() & GLPlatformSurface::SupportAlpha)
+            m_surfaceFlags |= GraphicsSurface::Alpha;
+
+        if (m_attributes.premultipliedAlpha)
+            m_surfaceFlags |= GraphicsSurface::PremultipliedAlpha;
+
+        // synchronize the attributes,
+        m_attributes.stencil = m_offScreenSurface->attributes() & GLPlatformSurface::SupportStencil;
+        m_attributes.depth = m_offScreenSurface->attributes() & GLPlatformSurface::SupportDepth;
+        m_attributes.alpha = m_offScreenSurface->attributes() & GLPlatformSurface::SupportAlpha;
+
+        m_surfaceHandle = m_offScreenSurface->handle();
+    }
+
+    return true;
+}
+
+bool AcceleratedPlatformLayer::makeContextCurrent()
+{
+    bool success = m_offScreenContext->makeCurrent(m_offScreenSurface.get());
+
+    if (!m_offScreenContext->isValid()) {
+        // FIXME: Restore context
+        if (m_contextLostCallback)
+            m_contextLostCallback->onContextLost();
+
+        return false;
+    }
+
+    return success;
+}
+
+void AcceleratedPlatformLayer::setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback> callBack)
+{
+    m_contextLostCallback = callBack;
+}
+
+bool AcceleratedPlatformLayer::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context)
+{
+    if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
+        return false;
+
+    cairo_t* cr = context->cr();
+    context->save();
+
+    RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data(
+                                                        const_cast<unsigned char*>(imagePixels), CAIRO_FORMAT_ARGB32, imageWidth, imageHeight, imageWidth * 4));
+
+    cairo_rectangle(cr, 0, 0, canvasWidth, canvasHeight);
+
+    // OpenGL keeps the pixels stored bottom up, so we need to flip the image here.
+    cairo_matrix_t matrix;
+    cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, imageHeight);
+    cairo_set_matrix(cr, &matrix);
+    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source_surface(cr, imageSurface.get(), 0, 0);
+    cairo_fill(cr);
+    context->restore();
+
+    return true;
+}
+
+void AcceleratedPlatformLayer::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, int width, int height)
+{
+    int totalBytes = 4 * width * height;
+
+    OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
+    if (!pixels)
+        return;
+
+    readRenderingResults(pixels.get(), totalBytes , width , height);
+
+#if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
+    cairo_surface_t* surface = imageBuffer->getSurface();
+    if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
+        // TODO: premultipliedAlpha currently not getting applied. Need to apply the value properly.
+        if (!m_attributes.premultipliedAlpha) {
+            for (int i = 0; i < totalBytes; i = 4) {
+                // Premultiply alpha.
+                pixels[i+0] = std::min(255, pixels[i+0] * pixels[i+3] / 255);
+                pixels[i+1] = std::min(255, pixels[i+1] * pixels[i+3] / 255);
+                pixels[i+2] = std::min(255, pixels[i+2] * pixels[i+3] / 255);
+            }
+        }
+    }
+#endif
+    paintToCanvas(pixels.get(), width, height,
+                  imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext());
+}
+
+PassRefPtr<ImageData> AcceleratedPlatformLayer::paintRenderingResultsToImageData(int width, int height)
+{
+    // Reading premultiplied alpha would involve unpremultiplying, which is
+    // lossy
+    if (m_attributes.premultipliedAlpha)
+        return 0;
+
+    RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height));
+    unsigned char* pixels = imageData->data()->data();
+    int totalBytes = 4 * width * height;
+
+    readRenderingResults(pixels, totalBytes, width, height);
+
+    // Convert to RGBA
+    for (int i = 0; i < totalBytes; i = 4)
+        std::swap(pixels[i], pixels[i+2]);
+
+    return imageData.release();
+}
+
+void AcceleratedPlatformLayer::markContextChanged()
+{
+    m_layerComposited = false;
+    m_swapBuffers = true;
+}
+
+bool AcceleratedPlatformLayer::swapPlatformSurfaces()
+{
+    if (!m_swapBuffers)
+        return true;
+
+    makeContextCurrent();
+    m_swapBuffers = false;
+    m_offScreenSurface->swapBuffers();
+    m_layerComposited = true;
+    return true;
+}
+
+void AcceleratedPlatformLayer::prepareTexture(int width, int height)
+{
+    if (m_layerComposited)
+        return;
+
+    GLuint internalColorFormat = 0;
+    if (m_attributes.alpha)
+        internalColorFormat = GL_RGBA;
+    else
+        internalColorFormat = GL_RGB;
+
+    makeContextCurrent();
+    GL_CMD(glActiveTexture(GL_TEXTURE0));
+    GL_CMD(glBindTexture(GL_TEXTURE_2D, m_compositorTexture));
+    GL_CMD(glCopyTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, 0, 0, width, height, 0));
+    GL_CMD(glBindTexture(GL_TEXTURE_2D, m_state->boundTexture0));
+    GL_CMD(glActiveTexture(m_state->activeTexture));
+    GL_CMD(glFinish());
+
+    m_layerComposited = true;
+}
+
+void AcceleratedPlatformLayer::readRenderingResults(unsigned char *pixels, int pixelsSize, int width, int height)
+{
+    int totalBytes = width * height * 4;
+    if (pixelsSize < totalBytes)
+        return;
+
+    makeContextCurrent();
+    if (m_attributes.antialias)
+        notImplemented();
+
+    GLint packAlignment = 4;
+    bool mustRestorePackAlignment = false;
+    GL_CMD(glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment));
+    if (packAlignment > 4) {
+        pixelStorei(GL_PACK_ALIGNMENT, 4);
+        mustRestorePackAlignment = true;
+    }
+
+    GL_CMD(glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+    // Convert to BGRA
+    for (int i = 0; i < totalBytes; i = 4)
+        std::swap(pixels[i], pixels[i+2]);
+
+    if (mustRestorePackAlignment)
+        pixelStorei(GL_PACK_ALIGNMENT, packAlignment);
+}
+
+void AcceleratedPlatformLayer::reshape(int width, int height)
+{
+    if ((m_width == width) && (m_height == height))
+        return;
+
+    m_width = width;
+    m_height = height;
+    makeContextCurrent();
+
+    if (m_offScreenSurface && (m_offScreenSurface->attributes() & GLPlatformSurface::DoubleBuffered)) {
+        m_offScreenSurface->swapBuffers();
+        m_offScreenSurface->setGeometry(IntRect(0, 0, m_width, m_height));
+    }
+    // FIXME: Handle resize case for single buffered surface.
+
+    m_surfaceHandle = m_offScreenSurface->handle();
+
+    if (m_attributes.antialias)
+        notImplemented();
+
+    // Initialize renderbuffers to 0.
+    GLfloat clearColorValue[] = {0, 0, 0, 0}, clearDepthValue = 0;
+    GLint clearStencilValue = 0;
+    GLboolean colorMaskValue[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMaskValue = GL_TRUE;
+    GLuint stencilMask = 0xffffffff;
+    GLboolean isScissorEnabled = GL_FALSE;
+    GLboolean isDitherEnabled = GL_FALSE;
+
+    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
+
+    GL_CMD(glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColorValue));
+    GL_CMD(glClearColor(0, 0, 0, 0));
+    GL_CMD(glGetBooleanv(GL_COLOR_WRITEMASK, colorMaskValue));
+    GL_CMD(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+
+    if (m_attributes.depth) {
+        GL_CMD(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepthValue));
+        GL_CMD(glClearDepthf(1.0));
+        GL_CMD(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMaskValue));
+        GL_CMD(glDepthMask(GL_TRUE));
+        clearMask |= GL_DEPTH_BUFFER_BIT;
+    }
+
+    if (m_attributes.stencil) {
+        GL_CMD(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencilValue));
+        GL_CMD(glClearStencil(0));
+        GL_CMD(glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask)));
+        GL_CMD(glStencilMaskSeparate(GL_FRONT, 0xffffffff));
+        clearMask |= GL_STENCIL_BUFFER_BIT;
+    }
+
+    isScissorEnabled = GL_CMD(glIsEnabled(GL_SCISSOR_TEST));
+    GL_CMD(glDisable(GL_SCISSOR_TEST));
+    isDitherEnabled = GL_CMD(glIsEnabled(GL_DITHER));
+    GL_CMD(glDisable(GL_DITHER));
+
+    GL_CMD(glClear(clearMask));
+
+    GL_CMD(glClearColor(clearColorValue[0], clearColorValue[1], clearColorValue[2], clearColorValue[3]));
+    GL_CMD(glColorMask(colorMaskValue[0], colorMaskValue[1], colorMaskValue[2], colorMaskValue[3]));
+
+    if (m_attributes.depth) {
+        GL_CMD(glClearDepthf(clearDepthValue));
+        GL_CMD(glDepthMask(depthMaskValue));
+    }
+    if (m_attributes.stencil) {
+        GL_CMD(glClearStencil(clearStencilValue));
+        GL_CMD(glStencilMaskSeparate(GL_FRONT, stencilMask));
+    }
+
+    if (isScissorEnabled)
+        GL_CMD(glEnable(GL_SCISSOR_TEST));
+    else
+        GL_CMD(glDisable(GL_SCISSOR_TEST));
+
+    if (isDitherEnabled)
+        GL_CMD(glEnable(GL_DITHER));
+    else
+        GL_CMD(glDisable(GL_DITHER));
+}
+
+void AcceleratedPlatformLayer::activeTexture(GC3Denum texture)
+{
+    if (m_state->activeTexture != texture) {
+        m_state->activeTexture = texture;
+        GraphicsContext3DInternal::activeTexture(texture);
+    }
+}
+
+void AcceleratedPlatformLayer::bindFramebuffer(GC3Denum target, Platform3DObject framebuffer)
+{
+    GLuint fbo = framebuffer;
+    if (framebuffer != m_state->boundFBO) {
+        m_state->boundFBO = fbo;
+        // FIXME : Below lines are workaround codes.(driver issue)
+        // PlatformSurface surface is not updated properly after binding FBO.
+        // It seems previous frame is remained.
+#if ENABLE(TIZEN_DDK_WORKAROUND)
+        if (flush && framebuffer && !m_layerComposited)
+            GL_CMD(glFlush());
+#endif
+        GraphicsContext3DInternal::bindFramebuffer(target, fbo);
+    }
+}
+
+#if ENABLE(TIZEN_DDK_WORKAROUND)
+void AcceleratedPlatformLayer::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level)
+{
+    // We should probably remove the tid that was set to framebuffer from m_renderTargetTextures
+    // if texture is no longer rendered to, but since this is temporary code that will be removed
+    // when the DDK is fixed, and that scenario is quite unlikely to happen, I'll just leave it as is.
+    if (target != Extensions3D::READ_FRAMEBUFFER && texture)
+        m_renderTargetTextures.add(texture);
+
+    GraphicsContext3DInternal::framebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void AcceleratedPlatformLayer::generateMipmap(GC3Denum target)
+{
+    // FIXME: Render to texture related driver issue.
+    // Remove GC3DOffscreen::generateMipmap and related code when driver issue is fixed.
+    // The rendered texture contents are not properly flushed before generating mipmaps.
+    int boundTexture;
+    GL_CMD(glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture));
+    if (m_renderTargetTextures.contains(boundTexture))
+        GL_CMD(glFlush());
+
+    GraphicsContext3DInternal::generateMipmap(target);
+}
+#endif
+
+void AcceleratedPlatformLayer::bindTexture(GC3Denum target, Platform3DObject texture)
+{
+    if (m_state->activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D) {
+        if (m_state->boundTexture0 == texture)
+            return;
+
+        m_state->boundTexture0 = texture;
+    }
+
+    GraphicsContext3DInternal::bindTexture(target, texture);
+}
+
+void AcceleratedPlatformLayer::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
+{
+    GraphicsContext3DInternal::bufferData(target, size, data, usage);
+
+    // FIXME : Driver issue!
+    // Following lines are temporary to avoid webgl conformance test failures.
+    // See draw-arrays-out-of-bounds.html.
+    // If a parameter size inputted to glBufferData is zero,
+    // GL_OUT_OF_MEMORY error is occurred while running in Mali driver.
+    if (!size) {
+        GC3Denum error = getError();
+        if (error == GL_OUT_OF_MEMORY)
+            return; // No error.
+        synthesizeGLError(error); // Push the error back again.
+    }
+}
+
+bool AcceleratedPlatformLayer::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+    if (!program) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+        return false;
+    }
+
+    makeContextCurrent();
+    GLint maxAttributeSize = 0;
+    GL_CMD(glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize));
+
+    GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
+    GLsizei nameLength = 0;
+    GLint size = 0;
+    GLenum type = 0;
+    GL_CMD(glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name));
+    if (!nameLength)
+        return false;
+
+    info.name = String(name, nameLength);
+    info.type = type;
+    info.size = size;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+    if (!program) {
+        synthesizeGLError(GL_INVALID_VALUE);
+        return false;
+    }
+
+    makeContextCurrent();
+    GC3Dint maxUniformSize = 0;
+    GL_CMD(glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize));
+
+    GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
+    GC3Dsizei nameLength = 0;
+    GC3Dint size = 0;
+    GC3Denum type = 0;
+    GL_CMD(glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name));
+    if (!nameLength)
+        return false;
+
+    info.name = String(name, nameLength);
+    info.type = type;
+    info.size = size;
+
+    // FIXME : "[0]" is added at end of name in WebGLRenderingContext::getActiveUniform()
+    // when isGLES2Compliant is only false. I can't understand the reason.
+    // I add "[0]" here to avoid faling webgl conformance test(get-active-test.html),
+    // but if it makes something wrong later, remove following lines
+    if (isGLES2Compliant() && info.size > 1 && !info.name.endsWith("[0]"))
+        info.name.append("[0]");
+
+    return true;
+}
+
+void AcceleratedPlatformLayer::getFloatv(GC3Denum pname, GC3Dfloat* value)
+{
+    GraphicsContext3DInternal::getFloatv(pname, value);
+
+    // FIXME : Fllowing lines are for fixing SGX & Mali driver issue.
+    switch (pname) {
+    case GL_ALIASED_POINT_SIZE_RANGE:
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+        if (value[0] == value[1]) {
+            if (!value[0])
+                value[1] = 1.0;
+            else {
+                if (value[0] < 1.0)
+                    value[1] = 1.0;
+                else
+                    value[0] = 1.0;
+            }
+        } else {
+            if (value[0] < value[1]) {
+                if (value[1] < 1.0) {
+                    value[0] = value[1];
+                    value[1] = 1.0;
+                } else
+                    value[0] = 1.0;
+            } else {
+                if (value[0] < 1.0)
+                    value[1] = 1.0;
+                else {
+                    value[1] = value[0];
+                    value[0] = 1.0;
+                }
+            }
+        }
+        break;
+    }
+}
+
+void AcceleratedPlatformLayer::getIntegerv(GC3Denum pname, GC3Dint* value)
+{
+    makeContextCurrent();
+    GL_CMD(glGetIntegerv(pname, value));
+}
+
+void AcceleratedPlatformLayer::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+    if (!updateViewportCache(x, y, width, height))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glViewport(x, y, width, height));
+}
+
+void AcceleratedPlatformLayer::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+    if (!updateStencilOpCache(fail, zfail, zpass))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glStencilOp(fail, zfail, zpass));
+}
+
+void AcceleratedPlatformLayer::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+    if (!updateStencilFuncCache(func, ref, mask))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glStencilFunc(func, ref, mask));
+}
+
+void AcceleratedPlatformLayer::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+    if (!updateScissorCache(x, y, width, height))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glScissor(x, y, width, height));
+}
+
+void AcceleratedPlatformLayer::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+    if (!updatePixelStoreiCache(pname, param))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glPixelStorei(pname, param));
+}
+
+GC3Dboolean AcceleratedPlatformLayer::isEnabled(GC3Denum cap)
+{
+    State::CapabilityState state = getCapabilityState(cap);
+    if (state != State::CapabilityUnknown)
+        return state == State::CapabilityEnabled ? true : false;
+
+    makeContextCurrent();
+    return GL_CMD(glIsEnabled(cap));
+}
+
+void AcceleratedPlatformLayer::enable(GC3Denum cap)
+{
+    if (!updateCapabilityCache(cap, State::CapabilityEnabled))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glEnable(cap));
+}
+
+void AcceleratedPlatformLayer::disable(GC3Denum cap)
+{
+    if (!updateCapabilityCache(cap, State::CapabilityDisabled))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glDisable(cap));
+}
+
+void AcceleratedPlatformLayer::depthMask(GC3Dboolean flag)
+{
+    if (!updateDepthMaskCache(flag))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glDepthMask(flag));
+}
+
+void AcceleratedPlatformLayer::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+    if (!updateBlendFuncCache(sfactor, dfactor))
+        return;
+
+    makeContextCurrent();
+    GL_CMD(glBlendFunc(sfactor, dfactor));
+}
+
+// below functions are for ANGLE integration
+void AcceleratedPlatformLayer::compileShader(Platform3DObject shader)
+{
+    ASSERT(shader);
+    makeContextCurrent();
+
+    int GLshaderType;
+    ANGLEShaderType shaderType;
+
+    GL_CMD(glGetShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType));
+
+    if (GLshaderType == GraphicsContext3D::VERTEX_SHADER)
+        shaderType = SHADER_TYPE_VERTEX;
+    else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER)
+        shaderType = SHADER_TYPE_FRAGMENT;
+    else
+        return; // Invalid shader type.
+
+    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+    if (result == m_shaderSourceMap.end())
+        return;
+
+    ShaderSourceEntry& entry = result->second;
+
+    String translatedShaderSource;
+    String shaderInfoLog;
+
+    bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog);
+
+    entry.log = shaderInfoLog;
+    entry.isValid = isValid;
+
+    if (!isValid)
+        return; // Shader didn't validate, don't move forward with compiling translated source.
+
+    int len = entry.source.length();
+    CString cstr = entry.source.utf8();
+    const char* s = cstr.data();
+
+    GL_CMD(glShaderSource(shader, 1, &s, &len));
+    GL_CMD(glCompileShader(shader));
+
+}
+
+void AcceleratedPlatformLayer::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
+{
+    ASSERT(shader);
+
+    makeContextCurrent();
+
+    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+    switch (pname) {
+    case GraphicsContext3D::DELETE_STATUS:
+    case GraphicsContext3D::SHADER_TYPE:
+        GL_CMD(glGetShaderiv(shader, pname, value));
+        break;
+    case GraphicsContext3D::COMPILE_STATUS:
+        if (result == m_shaderSourceMap.end()) {
+            *value = static_cast<int>(false);
+            return;
+        }
+        *value = static_cast<int>(result->second.isValid);
+        break;
+    case GraphicsContext3D::INFO_LOG_LENGTH:
+        if (result == m_shaderSourceMap.end()) {
+            *value = 0;
+            return;
+        }
+        *value = getShaderInfoLog(shader).length();
+        break;
+    case GraphicsContext3D::SHADER_SOURCE_LENGTH:
+        *value = getShaderSource(shader).length();
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+    }
+}
+
+String AcceleratedPlatformLayer::getShaderInfoLog(Platform3DObject shader)
+{
+    ASSERT(shader);
+
+    makeContextCurrent();
+
+    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+    if (result == m_shaderSourceMap.end())
+        return String();
+
+    ShaderSourceEntry entry = result->second;
+    if (!entry.isValid)
+        return entry.log;
+
+    GLint length = 0;
+    GL_CMD(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length));
+    if (!length)
+        return String();
+
+    GLsizei size = 0;
+    OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]);
+    GL_CMD(glGetShaderInfoLog(shader, length, &size, info.get()));
+
+    return String(info.get());
+}
+
+String AcceleratedPlatformLayer::getShaderSource(Platform3DObject shader)
+{
+    ASSERT(shader);
+
+    makeContextCurrent();
+
+    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+    if (result == m_shaderSourceMap.end())
+        return String();
+
+    return result->second.source;
+}
+
+void AcceleratedPlatformLayer::shaderSource(Platform3DObject shader, const String& string)
+{
+    ASSERT(shader);
+
+    makeContextCurrent();
+
+    ShaderSourceEntry entry;
+
+    entry.source = string;
+    entry.isValid = false;
+
+    m_shaderSourceMap.set(shader, entry);
+}
+
+bool AcceleratedPlatformLayer::updateBlendFuncCache(GC3Denum sourceFactor, GC3Denum destinationFactor)
+{
+    if (m_state->m_state & State::BlendFuncCacheDirty)
+        m_state->m_state &= ~State::BlendFuncCacheDirty;
+    else if (m_state->sourceFactor == sourceFactor && m_state->destinationFactor == destinationFactor)
+        return false;
+
+    m_state->sourceFactor = sourceFactor;
+    m_state->destinationFactor = destinationFactor;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updateDepthMaskCache(GC3Dboolean depthMask)
+{
+    if (m_state->m_state & State::DepthMaskCacheDirty)
+        m_state->m_state &= ~State::DepthMaskCacheDirty;
+    else if (m_state->depthMask == depthMask)
+        return false;
+
+    m_state->depthMask = depthMask;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updateScissorCache(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+    if (m_state->m_state & State::ScissorCacheDirty)
+        m_state->m_state &= ~State::ScissorCacheDirty;
+    else if (m_state->scissorX == x && m_state->scissorY == y && m_state->scissorWidth == width && m_state->scissorHeight == height)
+        return false;
+
+    m_state->scissorX = x;
+    m_state->scissorY = y;
+    m_state->scissorWidth = width;
+    m_state->scissorHeight = height;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updateStencilFuncCache(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+    if (m_state->m_state & State::StencilFuncCacheDirty)
+        m_state->m_state &= ~State::StencilFuncCacheDirty;
+    else if (m_state->stencilFunc == func && m_state->stencilRef == ref && m_state->stencilMask == mask)
+        return false;
+
+    m_state->stencilFunc = func;
+    m_state->stencilRef = ref;
+    m_state->stencilMask = mask;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updateStencilOpCache(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+    return true;
+
+    if (m_state->m_state & State::StencilOpCacheDirty)
+        m_state->m_state &= ~State::StencilOpCacheDirty;
+    else if (m_state->stencilFail == fail && m_state->stencilZFail == zfail && m_state->stencilZPass == zpass)
+        return false;
+
+    m_state->stencilFail = fail;
+    m_state->stencilZFail = zfail;
+    m_state->stencilZPass = zpass;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updateViewportCache(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+    if (m_state->m_state & State::ViewportCacheDirty)
+        m_state->m_state &= ~State::ViewportCacheDirty;
+    else if (m_state->viewportX == x && m_state->viewportY == y && m_state->viewportWidth == width && m_state->viewportHeight == height)
+        return false;
+
+    m_state->viewportX = x;
+    m_state->viewportY = y;
+    m_state->viewportWidth = width;
+    m_state->viewportHeight = height;
+    return true;
+}
+
+bool AcceleratedPlatformLayer::updatePixelStoreiCache(GC3Denum pname, GC3Dint param)
+{
+    State::PixelStoreIntMap::const_iterator it = m_state->pixelStoreIntMap.find(pname);
+    if (it != m_state->pixelStoreIntMap.end() && it->second == param)
+        return false;
+
+    m_state->pixelStoreIntMap.set(pname, param);
+    return true;
+}
+
+State::CapabilityState AcceleratedPlatformLayer::getCapabilityState(GC3Denum cap)
+{
+    State::CapabilityStateMap::const_iterator it = m_state->capabilityStateMap.find(cap);
+    if (it == m_state->capabilityStateMap.end())
+        return State::CapabilityUnknown;
+
+    return it->second;
+}
+
+bool AcceleratedPlatformLayer::updateCapabilityCache(GC3Denum cap, State::CapabilityState isEnabled)
+{
+    State::CapabilityStateMap::const_iterator it = m_state->capabilityStateMap.find(cap);
+    if (it != m_state->capabilityStateMap.end() && it->second == isEnabled)
+        return false;
+
+    m_state->capabilityStateMap.set(cap, isEnabled);
+    return true;
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.h b/Source/WebCore/platform/graphics/efl/tizen/AcceleratedPlatformLayer.h
new file mode 100644 (file)
index 0000000..e004592
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+    Copyright (C) 2011 Samsung Electronics
+    Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef AcceleratedPlatformLayer_h
+#define AcceleratedPlatformLayer_h
+
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+
+#include "GLPlatformContext.h"
+#include "GraphicsContext3D.h"
+#include "GraphicsContext3DInternal.h"
+#include "GraphicsSurface.h"
+#include "TextureMapperPlatformLayer.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class HostWindow;
+struct State {
+// This is based on initial work done here: https://bugs.webkit.org/show_bug.cgi?id=110883
+public:
+    State();
+    ~State();
+
+    enum state {
+        BlendFuncCacheDirty  = 0x01,
+        DepthMaskCacheDirty = 0x02,
+        StencilFuncCacheDirty = 0x04,
+        StencilOpCacheDirty = 0x08,
+        ViewportCacheDirty = 0x10,
+        ScissorCacheDirty = 0x20
+    };
+
+    enum CapabilityState {
+        CapabilityUnknown = 0x01,
+        CapabilityEnabled = 0x02,
+        CapabilityDisabled = 0x04
+    };
+
+    typedef unsigned StateAttributes;
+
+
+    GC3Denum activeTexture;
+    GC3Duint boundFBO;
+    GC3Duint boundTexture0;
+
+    // Used by glBlendFunc.
+    GC3Denum sourceFactor;
+    GC3Denum destinationFactor;
+
+    // Used by glDepthMask.
+    GC3Dboolean depthMask;
+
+    // Used by glScissor.
+    GC3Dint scissorX;
+    GC3Dint scissorY;
+    GC3Dsizei scissorWidth;
+    GC3Dsizei scissorHeight;
+
+    // Used by glStencilFunc.
+    GC3Denum stencilFunc;
+    GC3Dint stencilRef;
+    GC3Duint stencilMask;
+
+    // Used by glStencilOp.
+    GC3Denum stencilFail;
+    GC3Denum stencilZFail;
+    GC3Denum stencilZPass;
+
+    // Used by glViewport.
+    GC3Dint viewportX;
+    GC3Dint viewportY;
+    GC3Dsizei viewportWidth;
+    GC3Dsizei viewportHeight;
+
+    // Used by glPixelStorei.
+    typedef HashMap<GC3Denum, GC3Dint> PixelStoreIntMap;
+    PixelStoreIntMap pixelStoreIntMap;
+
+    // Used by glEnable and glDisable.
+    typedef HashMap<GC3Denum, CapabilityState> CapabilityStateMap;
+    CapabilityStateMap capabilityStateMap;
+
+    StateAttributes m_state;
+};
+
+class AcceleratedPlatformLayer : public GraphicsContext3DInternal
+        , public TextureMapperPlatformLayer {
+public:
+    static PassOwnPtr<AcceleratedPlatformLayer> create(GraphicsContext3D::Attributes, GraphicsContext3D::RenderStyle);
+    virtual ~AcceleratedPlatformLayer();
+
+    virtual Platform3DObject platformTexture() const OVERRIDE { return m_compositorTexture; }
+    virtual PlatformLayer* platformLayer() const OVERRIDE;
+    virtual PlatformGraphicsContext3D platformGraphicsContext3D() const OVERRIDE { return m_offScreenContext->handle(); }
+
+    virtual void  paintRenderingResultsToCanvas(ImageBuffer*, int, int) OVERRIDE;
+    virtual PassRefPtr<ImageData> paintRenderingResultsToImageData(int width, int height) OVERRIDE;
+    virtual bool paintsIntoCanvasBuffer() const OVERRIDE { return false; }
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float) OVERRIDE { }
+    virtual bool paintToCanvas(const unsigned char*, int, int,  int, int, PlatformContextCairo*) OVERRIDE;
+
+    virtual bool swapPlatformSurfaces() OVERRIDE;
+    virtual PlatformBufferHandle copyToGraphicsSurface() OVERRIDE { return m_surfaceHandle; }
+    virtual PlatformBufferHandle graphicsSurfaceToken() OVERRIDE const { return m_surfaceHandle; }
+    virtual int graphicsSurfaceFlags() const OVERRIDE { return m_surfaceFlags; }
+
+    virtual bool makeContextCurrent() OVERRIDE;
+    virtual void prepareTexture(int, int) OVERRIDE;
+    virtual void reshape(int, int) OVERRIDE;
+    virtual void readRenderingResults(unsigned char* pixels, int pixelsSize, int width, int height) OVERRIDE;
+    virtual void markContextChanged() OVERRIDE;
+    virtual void markLayerComposited() OVERRIDE { m_layerComposited = true; }
+    virtual bool layerComposited() const OVERRIDE { return m_layerComposited; }
+
+    virtual void activeTexture(GC3Denum) OVERRIDE;
+    virtual void bindFramebuffer(GC3Denum, Platform3DObject) OVERRIDE;
+    virtual void bindTexture(GC3Denum, Platform3DObject) OVERRIDE;
+    virtual void bufferData(GC3Denum, GC3Dsizeiptr, const void*, GC3Denum) OVERRIDE;
+    virtual bool getActiveAttrib(Platform3DObject, GC3Duint, ActiveInfo&) OVERRIDE;
+    virtual bool getActiveUniform(Platform3DObject, GC3Duint, ActiveInfo&) OVERRIDE;
+    virtual void getFloatv(GC3Denum, GC3Dfloat*) OVERRIDE;
+    virtual void getIntegerv(GC3Denum, GC3Dint*) OVERRIDE;
+    virtual void viewport(GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) OVERRIDE;
+    virtual void stencilOp(GC3Denum, GC3Denum, GC3Denum) OVERRIDE;
+    virtual void stencilFunc(GC3Denum, GC3Dint, GC3Duint) OVERRIDE;
+    virtual void scissor(GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) OVERRIDE;
+    virtual void pixelStorei(GC3Denum, GC3Dint) OVERRIDE;
+    virtual GC3Dboolean isEnabled(GC3Denum) OVERRIDE;
+    virtual void enable(GC3Denum) OVERRIDE;
+    virtual void disable(GC3Denum) OVERRIDE;
+    virtual void depthMask(GC3Dboolean) OVERRIDE;
+    virtual void blendFunc(GC3Denum sfactor, GC3Denum dfactor) OVERRIDE;
+#if ENABLE(TIZEN_DDK_WORKAROUND)
+    virtual void framebufferTexture2D(GC3Denum, GC3Denum, GC3Denum, Platform3DObject, GC3Dint);
+    virtual void generateMipmap(GC3Denum);
+#endif
+
+    virtual void setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback>) OVERRIDE;
+
+private:
+    typedef struct {
+        String source;
+        String log;
+        bool isValid;
+    } ShaderSourceEntry;
+
+    AcceleratedPlatformLayer(GraphicsContext3D::Attributes, GraphicsContext3D::RenderStyle);
+    virtual bool initialize(HostWindow*) OVERRIDE;
+    bool initializeSurface();
+    void releaseResources();
+    // Angle intgration block
+    virtual void compileShader(Platform3DObject);
+    virtual void getShaderiv(Platform3DObject, GC3Denum, GC3Dint*);
+    virtual String getShaderInfoLog(Platform3DObject);
+    virtual String getShaderSource(Platform3DObject);
+    virtual void shaderSource(Platform3DObject, const String&);
+
+    // State Cache.
+    bool updateBlendFuncCache(GC3Denum, GC3Denum);
+    bool updateDepthMaskCache(GC3Dboolean);
+    bool updateScissorCache(GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei);
+    bool updateStencilFuncCache(GC3Denum, GC3Dint, GC3Duint);
+    bool updateStencilOpCache(GC3Denum, GC3Denum, GC3Denum);
+    bool updateViewportCache(GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei);
+    bool updatePixelStoreiCache(GC3Denum, GC3Dint);
+    bool updateCapabilityCache(GC3Denum, State::CapabilityState);
+    State::CapabilityState getCapabilityState(GC3Denum);
+
+    GLuint m_compositorTexture;
+    bool m_layerComposited :1;
+    bool m_swapBuffers :1;
+    int m_width;
+    int m_height;
+    GraphicsSurface::Flags m_surfaceFlags;
+    PlatformBufferHandle m_surfaceHandle;
+    GraphicsContext3D::RenderStyle m_renderStyle;
+    OwnPtr<State> m_state;
+    OwnPtr<GLPlatformContext> m_offScreenContext;
+    OwnPtr<GLPlatformSurface> m_offScreenSurface;
+    OwnPtr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback;
+#if ENABLE(TIZEN_DDK_WORKAROUND)
+    HashSet<Platform3DObject> m_renderTargetTextures;
+#endif
+    HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // AcceleratedPlatformLayer_h
index d242512..2fc4745 100755 (executable)
 #include "GraphicsContext3DInternal.h"
 
 #include "Extensions3DTizen.h"
-#if ENABLE(WEBGL)
+#if ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+#include "AcceleratedPlatformLayer.h"
+#elif ENABLE(WEBGL)
 #include "GraphicsContext3DOffscreen.h"
 #endif
-
 #if ENABLE(TIZEN_WEBKIT2)
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
@@ -54,13 +55,22 @@ PassOwnPtr<GraphicsContext3DInternal> GraphicsContext3DInternal::create(Graphics
         return nullptr;
 #endif
 
-#if ENABLE(WEBGL)
+#if ENABLE(WEBGL) && !ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
     return GraphicsContext3DOffscreen::create(attrs, hostWindow);
 #else
     return nullptr;
 #endif
 }
 
+PassOwnPtr<GraphicsContext3DInternal> GraphicsContext3DInternal::create(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
+{
+#if ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+    return AcceleratedPlatformLayer::create(attrs, renderStyle);
+#else
+    return nullptr;
+#endif
+}
+
 GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, GraphicsContext3D::RenderStyle renderStyle)
     : m_attributes(attrs)
     , m_renderStyle(renderStyle)
index 9e9edaf..22fb750 100755 (executable)
@@ -57,6 +57,7 @@ class GraphicsContext3DInternal
 {
 public:
     static PassOwnPtr<GraphicsContext3DInternal> create(GraphicsContext3D::Attributes, HostWindow*, bool);
+    static PassOwnPtr<GraphicsContext3DInternal> create(GraphicsContext3D::Attributes, GraphicsContext3D::RenderStyle);
     virtual ~GraphicsContext3DInternal();
 
     PlatformGraphicsContext3D platformGraphicsContext3D() const { return m_context; }
index 00bfdf9..86108e4 100644 (file)
@@ -41,20 +41,26 @@ namespace WebCore {
 PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, RenderStyle renderStyle)
 {
     bool renderDirectlyToEvasGLObject = (renderStyle == RenderDirectlyToHostWindow);
-
+#if PLATFORM(WAYLAND)
+    OwnPtr<GraphicsContext3DInternal> internal = GraphicsContext3DInternal::create(attrs, renderStyle);
+    if (!internal)
+        return 0;
+#else
     OwnPtr<GraphicsContext3DInternal> internal = GraphicsContext3DInternal::create(attrs, hostWindow, renderDirectlyToEvasGLObject);
     if (!internal)
         return 0;
+#endif
 
     RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, renderDirectlyToEvasGLObject));
     context->m_internal = internal.release();
 
-#if USE(ACCELERATED_COMPOSITING)
+#if USE(ACCELERATED_COMPOSITING) && !PLATFORM(WAYLAND)
 #if !USE(TIZEN_TEXTURE_MAPPER)
     if (!renderDirectlyToEvasGLObject)
         static_cast<EflLayer*>(context->platformLayer())->setContentsToCanvas(context.get());
 #endif
 #endif
+
     return context.release();
 }
 
index 110c660..bd18d4b 100644 (file)
 #if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
 
 #include "EGLHelper.h"
+#include <wtf/HashMap.h>
 
 #include <stdlib.h>
 #include <string.h>
 
-#include <wtf/HashMap.h>
-
 namespace WebCore {
 
 #if !defined(EGL_FORMAT_RGBA_8888_EXACT_KHR)
@@ -215,7 +214,7 @@ void EGLConfigPool::createConfig(EGLint expectedSurfaceType, GLPlatformSurface::
     static bool isVendorMesa = EGLHelper::isVendor("mesa");
     static bool isVendorArm = EGLHelper::isVendor("arm");
 
-    if (isVendorMesa)
+    if (isVendorMesa || isVendorImagination)
         expectedDepthSize = attributes & GLPlatformSurface::SupportDepth ? 24 : 0;
 
     if (!expectedAlpha && isVendorImagination)
@@ -323,7 +322,8 @@ EGLConfigSelector::EGLConfigSelector(GLPlatformSurface::SurfaceAttributes attrib
     : m_attributes(attributes)
 {
     static bool isVendorMesa = EGLHelper::isVendor("mesa");
-    if (isVendorMesa) {
+    static bool isVendorImagination = EGLHelper::isVendor("imagination");
+    if (isVendorMesa || isVendorImagination) {
         if ((m_attributes & GLPlatformSurface::SupportStencil) || (m_attributes & GLPlatformSurface::SupportDepth)) {
             m_attributes |= GLPlatformSurface::SupportStencil;
             m_attributes |= GLPlatformSurface::SupportDepth;
index 0c6bdc7..a1a191e 100644 (file)
@@ -73,7 +73,7 @@ bool EGLOffScreenContext::initialize(GLPlatformSurface* surface, PlatformContext
         return false;
 
     static bool isRobustnessExtensionSupported = GLPlatformContext::supportsEGLExtension(display, "EGL_EXT_create_context_robustness");
-    if (isRobustnessExtensionSupported)
+    if (!(surface->attributes() & GLPlatformSurface::Lockable) && isRobustnessExtensionSupported)
         m_contextHandle = eglCreateContext(display, config, sharedContext, contextRobustnessAttributes);
 
     if (m_contextHandle != EGL_NO_CONTEXT) {
index 931eb4d..8d493a4 100644 (file)
@@ -32,8 +32,6 @@
 
 #if PLATFORM(X11)
 #include "X11Helper.h"
-#elif PLATFORM(WAYLAND)
-#include "WaylandHelper.h"
 #endif
 
 namespace WebCore {
@@ -42,7 +40,7 @@ namespace WebCore {
 typedef X11Helper NativeWrapper;
 typedef Display NativeSharedDisplay;
 #elif PLATFORM(WAYLAND)
-typedef WaylandHelper NativeWrapper;
+typedef WaylandDisplay NativeWrapper;
 typedef struct wl_display NativeSharedDisplay;
 #endif
 
@@ -56,6 +54,14 @@ struct EGLDisplayConnection {
 
     EGLDisplayConnection(NativeSharedDisplay* display = 0)
     {
+        m_terminateNativeDisplay = false;
+#if PLATFORM(WAYLAND)
+        if (!display) {
+            NativeWrapper::connect();
+            m_terminateNativeDisplay = true;
+            display = NativeWrapper::instance()->nativeDisplay();
+        }
+#endif
         if (display)
             m_eglDisplay = eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display));
         else
@@ -102,15 +108,24 @@ private:
         eglTerminate(m_eglDisplay);
         eglReleaseThread();
         m_eglDisplay = EGL_NO_DISPLAY;
+#if PLATFORM(WAYLAND)
+        if (m_terminateNativeDisplay)
+            NativeWrapper::disconnect();
+#endif
     }
 
     EGLDisplay m_eglDisplay;
+    bool m_terminateNativeDisplay :1;
 };
 
 PlatformDisplay EGLHelper::eglDisplay()
 {
     // Display connection will only be broken at program shutdown.
+#if PLATFORM(WAYLAND)
+    static EGLDisplayConnection displayConnection(0);
+#else
     static EGLDisplayConnection displayConnection(NativeWrapper::nativeDisplay());
+#endif
     return displayConnection.display();
 }
 
@@ -124,6 +139,15 @@ PlatformDisplay EGLHelper::currentDisplay()
     return display;
 }
 
+#if PLATFORM(WAYLAND)
+PlatformDisplay EGLHelper::compositorEGLDisplay(NativeSharedDisplay* display)
+{
+    // Display connection will only be broken at program shutdown.
+    static EGLDisplayConnection displayConnection(display);
+    return displayConnection.display();
+}
+#endif
+
 void EGLHelper::resolveEGLBindings(EGLDisplay eglDisplay)
 {
     static bool initialized = false;
@@ -152,7 +176,6 @@ void EGLHelper::resolveEGLBindings(EGLDisplay eglDisplay)
 #endif
         eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
         eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
-        eglImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
     } else
 #if PLATFORM(WAYLAND)
         LOG_ERROR("Platform doesn't support EGL_KHR_image_base or EGL_WL_bind_wayland_display. Support for these extensions is required for Hardware Acceleration.");
@@ -174,6 +197,9 @@ void EGLHelper::createEGLImage(EGLImageKHR* image, GLenum target, const EGLClien
     if (eglCreateImageKHR && eglDestroyImageKHR)
         tempHandle = eglCreateImageKHR(display, EGL_NO_CONTEXT, target, clientBuffer, attributes);
 
+    if (tempHandle == EGL_NO_IMAGE_KHR)
+        HandleEGLError("eglcreateimagekhr");
+
     *image = tempHandle;
 }
 
index bf3f1d1..85c39bf 100644 (file)
 #ifndef EGLHelper_h
 #define EGLHelper_h
 
-#if USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
+#if USE(EGL)
 
 #include "EGLSurface.h"
 #if PLATFORM(WAYLAND)
-#include "WaylandHelper.h"
+#include "WaylandDisplay.h"
 #endif
 #include <wtf/text/WTFString.h>
 
@@ -49,6 +49,9 @@ class EGLHelper {
 public:
     static PlatformDisplay eglDisplay();
     static PlatformDisplay currentDisplay();
+#if PLATFORM(WAYLAND)
+    static PlatformDisplay compositorEGLDisplay(wl_display*);
+#endif
     static void resolveEGLBindings(EGLDisplay = EGL_NO_DISPLAY);
     static void createEGLImage(EGLImageKHR*, GLenum, const EGLClientBuffer, const EGLint* = 0, EGLDisplay = EGL_NO_DISPLAY);
     static void destroyEGLImage(const EGLImageKHR, EGLDisplay = EGL_NO_DISPLAY);
index 7c9276b..e98f800 100644 (file)
 
 #include "EGLConfigSelector.h"
 #include "EGLHelper.h"
-#include "WaylandHelper.h"
+#include "WaylandDisplay.h"
 
 #include <wtf/UnusedParam.h>
 
 namespace WebCore {
-static int sharedBufferHandle = 0;
+
 EGLWindowSurface::EGLWindowSurface(const IntSize& size, GLPlatformSurface::SurfaceAttributes attributes)
     : EGLOffScreenSurface(attributes)
     , m_nativeWindow(0)
-    , m_surface(0)
 {
     if (!m_configSelector)
         return;
 
     if (!m_configSelector->surfaceContextConfig()) {
+        LOG_ERROR("No supported Configuration found.");
         destroy();
         return;
     }
 
-    m_surface = wl_compositor_create_surface(WaylandHelper::compositor());
+    m_surface = WaylandDisplay::instance()->createSurface();
 
     if (!m_surface) {
         LOG_ERROR("Failed to create surface.");
@@ -57,7 +57,7 @@ EGLWindowSurface::EGLWindowSurface(const IntSize& size, GLPlatformSurface::Surfa
         return;
     }
 
-    m_nativeWindow = wl_egl_window_create(m_surface, size.width(), size.height());
+    m_nativeWindow = wl_egl_window_create(m_surface->wlSurface(), size.width(), size.height());
 
     if (!m_nativeWindow) {
         LOG_ERROR("Failed to create Native Window.");
@@ -73,13 +73,14 @@ EGLWindowSurface::EGLWindowSurface(const IntSize& size, GLPlatformSurface::Surfa
         return;
     }
 
-    sharedBufferHandle++;
-    m_bufferHandle = sharedBufferHandle;
+    m_bufferHandle = m_surface->handle();
+    WaylandDisplay::instance()->syncDisplay();
+    m_rect = IntRect(0, 0, size.width(), size.height());
 }
 
 EGLWindowSurface::~EGLWindowSurface()
 {
-    if (m_nativeWindow || m_surface || (m_drawable != EGL_NO_SURFACE))
+    if (m_nativeWindow || (m_drawable != EGL_NO_SURFACE))
         LOG_ERROR("Resources not destroyed for surface with id: %d", m_bufferHandle);
 
     m_bufferHandle = 0;
@@ -87,28 +88,30 @@ EGLWindowSurface::~EGLWindowSurface()
 
 void EGLWindowSurface::swapBuffers()
 {
-    if (!eglSwapBuffers(m_sharedDisplay, m_drawable))
-        LOG_ERROR("Failed to SwapBuffers(%d).", eglGetError());
+    if (m_surface->ensureFrameCallBackDone() == -1)
+        return;
 
-    wl_display_dispatch(WaylandHelper::nativeDisplay());
+    m_surface->addFrameCallBack();
+
+    if (!eglSwapBuffers(m_sharedDisplay, m_drawable)) {
+        LOG_ERROR("Failed to SwapBuffers(%d).", eglGetError());
+        m_surface->deleteFrameCallBack();
+    }
 }
 
 void EGLWindowSurface::destroy()
 {
-    EGLOffScreenSurface::destroy();
+    if (m_surface)
+        m_surface->deleteFrameCallBack();
 
-    if (!m_nativeWindow && !m_surface)
-        return;
+    EGLOffScreenSurface::destroy();
 
     if (m_nativeWindow) {
         wl_egl_window_destroy(m_nativeWindow);
         m_nativeWindow = 0;
     }
 
-    if (m_surface) {
-        wl_surface_destroy(m_surface);
-        m_surface = 0;
-    }
+    m_surface = nullptr;
 }
 
 PlatformSurfaceConfig EGLWindowSurface::configuration()
@@ -116,6 +119,27 @@ PlatformSurfaceConfig EGLWindowSurface::configuration()
     return m_configSelector->surfaceContextConfig();
 }
 
+void EGLWindowSurface::setGeometry(const IntRect& rect)
+{
+    if (rect != m_rect) {
+        m_rect = rect;
+        m_surface->ensureFrameCallBackDone();
+        wl_egl_window_resize(m_nativeWindow, m_rect.width(), m_rect.height(), m_rect.x(), m_rect.y());
+        WaylandDisplay::instance()->syncDisplay();
+    }
+}
+
+bool EGLWindowSurface::lockSurface()
+{
+    static EGLint lockAttrib[] = { EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR, EGL_NONE };
+    return EGLHelper::lockSurface(m_drawable, lockAttrib);
+}
+
+bool EGLWindowSurface::unlockSurface()
+{
+    return EGLHelper::unlockSurface(m_drawable);
+}
+
 }
 
 #endif
index 862274b..d87e28c 100644 (file)
@@ -29,6 +29,7 @@
 #if PLATFORM(WAYLAND) && (USE(EGL) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE))
 
 #include "EGLSurface.h"
+#include "WaylandDisplay.h"
 
 namespace WebCore {
 
@@ -40,10 +41,13 @@ public:
     virtual void swapBuffers() OVERRIDE;
     virtual void destroy() OVERRIDE;
     virtual PlatformSurfaceConfig configuration() OVERRIDE;
+    virtual void setGeometry(const IntRect&) OVERRIDE;
+    virtual bool lockSurface() OVERRIDE;
+    virtual bool unlockSurface() OVERRIDE;
 
 private:
     struct wl_egl_window* m_nativeWindow;
-    struct wl_surface* m_surface;
+    OwnPtr<WaylandSurface> m_surface;
 };
 
 }
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/GraphicsSurfaceWayland.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/GraphicsSurfaceWayland.cpp
new file mode 100644 (file)
index 0000000..44191bf
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GraphicsSurface.h"
+
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && PLATFORM(WAYLAND)
+#include "NotImplemented.h"
+#include "PlatformTextureWayland.h"
+#include "TextureMapperGL.h"
+
+namespace WebCore {
+
+class GraphicsSurfacePrivate {
+public:
+    GraphicsSurfacePrivate()
+        : m_useLinearFilter(false)
+    {
+    }
+
+    GraphicsSurfacePrivate(PlatformBufferHandle token, const IntSize& size, bool useLinearFilter)
+        : m_useLinearFilter(useLinearFilter)
+    {
+        m_platformTexture = adoptPtr(new PlatformTextureWayland(token, size));
+    }
+
+    virtual ~GraphicsSurfacePrivate()
+    {
+    }
+
+    int getPlatformSurfaceTextureID()
+    {
+        int textureId = m_platformTexture->id();
+        if (!textureId) {
+            m_platformTexture->initialize(m_useLinearFilter);
+            textureId = m_platformTexture->id();
+        }
+
+        return textureId;
+    }
+
+private:
+    bool m_useLinearFilter : 1;
+    OwnPtr<PlatformTextureWayland> m_platformTexture;
+};
+
+PlatformBufferHandle GraphicsSurface::platformExport()
+{
+    return m_platformSurface;
+}
+
+uint32_t GraphicsSurface::platformGetTextureID()
+{
+    return m_private->getPlatformSurfaceTextureID();
+}
+
+void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
+{
+    bool alpha = m_canvasFlags & GraphicsSurface::Alpha;
+    int textureId = m_private->getPlatformSurfaceTextureID();
+    if (!textureId)
+        return;
+
+    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(textureId, alpha ? TextureMapperGL::SupportsBlending : 0, m_size, targetRect, transform, opacity, expandedIntSize(targetRect.size()), m_canvasFlags & GraphicsSurface::PremultipliedAlpha);
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags)
+{
+    return 0;
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(PlatformBufferHandle platformSurfaceID)
+{
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(IntSize(), 0));
+    surface->m_private = new GraphicsSurfacePrivate();
+    surface->m_platformSurface = platformSurfaceID;
+    return surface;
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, PlatformBufferHandle token, Flags canvasFlags)
+{
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+    surface->m_private = new GraphicsSurfacePrivate(token, size, canvasFlags & GraphicsSurface::UseLinearFilter);
+    surface->m_platformSurface = token;
+    surface->m_canvasFlags = canvasFlags;
+    surface->m_size = size;
+    return surface;
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, PlatformBufferHandle token)
+{
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+    surface->m_private = new GraphicsSurfacePrivate(token, size, flags & GraphicsSurface::UseLinearFilter);
+    surface->m_platformSurface = token;
+    surface->m_size = size;
+
+    return surface;
+}
+
+void GraphicsSurface::platformDestroy()
+{
+    delete m_private;
+    m_private = 0;
+}
+
+void GraphicsSurface::platformCopyToGLTexture(uint32_t, uint32_t, const IntRect&, const IntPoint&)
+{
+    notImplemented();
+}
+
+void GraphicsSurface::platformCopyFromFramebuffer(uint32_t, const IntRect&)
+{
+    notImplemented();
+}
+
+PlatformBufferHandle GraphicsSurface::platformFrontBuffer() const
+{
+    return m_platformSurface;
+}
+
+PlatformBufferHandle GraphicsSurface::platformSwapBuffers()
+{
+    notImplemented();
+    return 0;
+}
+
+PlatformBufferHandle GraphicsSurface::platformSwapBuffers(PlatformBufferHandle)
+{
+    notImplemented();
+    return 0;
+}
+
+char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
+{
+    notImplemented();
+    return 0;
+}
+
+void GraphicsSurface::platformUnlock()
+{
+    notImplemented();
+}
+
+PassOwnPtr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize& size, char* bits, int stride)
+{
+    notImplemented();
+    return nullptr;
+}
+
+PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect& rect)
+{
+    notImplemented();
+    return 0;
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.cpp
new file mode 100644 (file)
index 0000000..1bd6051
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+    Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+
+#include "PlatformTextureWayland.h"
+
+namespace WebCore {
+PlatformTextureWayland::PlatformTextureWayland(int platformSurfaceID, const IntSize& size)
+    : m_buffer(0)
+    , m_platformSurfaceID(platformSurfaceID)
+    , m_textureSize(size)
+    , m_used(false)
+{
+}
+
+PlatformTextureWayland::~PlatformTextureWayland()
+{
+    if (m_buffer) {
+        m_buffer = 0;
+        WaylandDisplay* display = WaylandDisplay::instance();
+        if (display)
+            display->unMapBuffer(m_platformSurfaceID, this);
+    }
+}
+
+bool PlatformTextureWayland::initialize(bool useLinearFilter)
+{
+    if (m_buffer)
+        return true;
+
+    if (!m_platformSurfaceID) {
+        LOG_ERROR("ID is invalid!");
+        return 0;
+    }
+
+    if (!m_buffer) {
+        WaylandDisplay* display = WaylandDisplay::instance();
+        if (!display) {
+            LOG_ERROR("WaylandDisplay not initialized");
+            return false;
+        }
+
+        m_buffer = display->mapBuffer(m_platformSurfaceID, this, useLinearFilter);
+        if (!m_buffer) {
+            LOG_ERROR("Failed to map buffer for the surface");
+            return 0;
+        }
+    }
+
+    return true;
+}
+
+uint32_t PlatformTextureWayland::id() const
+{
+    return m_buffer ? m_buffer->textureId() :0;
+}
+
+void PlatformTextureWayland::bufferDestroyed()
+{
+    m_buffer = 0;
+    m_platformSurfaceID = 0;
+}
+
+};
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.h b/Source/WebCore/platform/graphics/surfaces/wayland/PlatformTextureWayland.h
new file mode 100644 (file)
index 0000000..4a111c1
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PlatformTextureWayland_h
+#define PlatformTextureWayland_h
+
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && ENABLE(TIZEN_ACCELERATED_PLATFORM_LAYER)
+#include "IntSize.h"
+#include "TextureMapperGL.h"
+#include "WaylandDisplay.h"
+#include "WaylandSurface.h"
+
+namespace WebCore {
+
+class PlatformTextureWayland : public PlatformSurfaceTexture
+                             , public WaylandBufferListener {
+public:
+    PlatformTextureWayland(int platformSurfaceID, const IntSize&);
+    ~PlatformTextureWayland();
+    bool initialize(bool useLinearFilter);
+    virtual uint32_t id() const OVERRIDE;
+    virtual int platformSurfaceId() const OVERRIDE { return m_platformSurfaceID; }
+    virtual void updateTexture() OVERRIDE { }
+    virtual void setUsed(bool used) OVERRIDE { m_used = used; }
+    virtual bool used() OVERRIDE { return m_used; }
+    virtual IntSize size() const OVERRIDE { return m_textureSize; }
+    virtual void bufferDestroyed() OVERRIDE;
+
+private:
+    WaylandBuffer* m_buffer;
+    PlatformBufferHandle m_platformSurfaceID;
+    IntSize m_textureSize;
+    bool m_used :1;
+};
+
+}
+#endif
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.cpp
new file mode 100644 (file)
index 0000000..30eab5a
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandCompositor.h"
+
+#include "EGLHelper.h"
+#include "GLPlatformContext.h"
+#include "WaylandSurface.h"
+#include <sys/time.h>
+
+namespace WebCore {
+
+WaylandCompositor* WaylandCompositor::m_instance = 0;
+#if !defined(PFNEGLBINDWAYLANDDISPLAYWL)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay, struct wl_display*);
+#endif
+
+#if !defined(PFNEGLUNBINDWAYLANDDISPLAYWL)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay, struct wl_display*);
+#endif
+
+static PFNEGLBINDWAYLANDDISPLAYWL bindWaylanddisplayWL = 0;
+static PFNEGLUNBINDWAYLANDDISPLAYWL unbindWaylanddisplayWL = 0;
+
+static const struct wl_compositor_interface compositorInterface = {
+    WaylandCompositor::compositorCreateSurface,
+    WaylandCompositor::compositorCreateRegion
+};
+
+WaylandCompositor* WaylandCompositor::initialize(wl_display* display, wl_display* nestedDisplay)
+{
+    if (!m_instance && display) {
+        m_instance = new WaylandCompositor(display, nestedDisplay);
+        if (!m_instance->m_eglDisplay) {
+            delete m_instance;
+            m_instance = 0;
+        }
+    }
+
+    return m_instance;
+}
+
+WaylandCompositor* WaylandCompositor::getInstance()
+{
+    return m_instance;
+}
+
+void WaylandCompositor::release()
+{
+    if (m_instance)
+        delete m_instance;
+
+    m_instance = 0;
+}
+
+WaylandCompositor::WaylandCompositor(wl_display* display, wl_display* nestedDisplay)
+    : m_global(0)
+    , m_nestedDisplay(nestedDisplay)
+{
+    if (!m_nestedDisplay) {
+        LOG_ERROR("WaylandCompositor Initialization failed: Invalid Nested Display.");
+        return;
+    }
+
+    m_eglDisplay = EGLHelper::compositorEGLDisplay(display);
+    if (m_eglDisplay == EGL_NO_DISPLAY) {
+        LOG_ERROR("WaylandCompositor Initialization failed: Unable to initialize EGL.");
+        return;
+    }
+
+    m_global = wl_global_create(m_nestedDisplay, &wl_compositor_interface, 1, this, WaylandCompositor::compositorBind);
+    if (!m_global)
+        return;
+
+    if (GLPlatformContext::supportsEGLExtension(m_eglDisplay, "EGL_WL_bind_wayland_display")) {
+        bindWaylanddisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL)eglGetProcAddress("eglBindWaylandDisplayWL");
+        unbindWaylanddisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL)eglGetProcAddress("eglUnbindWaylandDisplayWL");
+    } else {
+        LOG_ERROR("WaylandCompositor Initialization failed: EGL_WL_bind_wayland_display is not supported.");
+        m_eglDisplay = EGL_NO_DISPLAY;
+        return;
+    }
+
+    bool validConnection = false;
+    if (bindWaylanddisplayWL && unbindWaylanddisplayWL)
+        validConnection = bindWaylanddisplayWL(m_eglDisplay, m_nestedDisplay);
+
+    if (!validConnection) {
+        LOG_ERROR("WaylandCompositor Initialization failed: Unable to bind Wayland display.");
+        m_eglDisplay = EGL_NO_DISPLAY;
+        return;
+    }
+
+    EGLHelper::resolveEGLBindings(m_eglDisplay);
+    m_threadMutex = adoptPtr(new Mutex);
+}
+
+WaylandCompositor::~WaylandCompositor()
+{
+    if (!m_eglDisplay || !m_nestedDisplay)
+        return;
+
+    if (m_global) {
+        wl_global_destroy(m_global);
+        m_global = 0;
+    }
+
+    m_listenerMap.clear();
+    if (!m_bufferMarkedForDeletion.isEmpty()) {
+        deleteAllValues(m_bufferMarkedForDeletion);
+        m_bufferMarkedForDeletion.clear();
+    }
+
+    if (!m_bufferMap.isEmpty()) {
+        deleteAllValues(m_bufferMap);
+        m_bufferMap.clear();
+    }
+
+    if (bindWaylanddisplayWL && unbindWaylanddisplayWL)
+        unbindWaylanddisplayWL(m_eglDisplay, m_nestedDisplay);
+}
+
+void WaylandCompositor::cleanUpBufferMap()
+{
+    if (m_bufferMarkedForDeletion.isEmpty())
+        return;
+
+    if (!m_listenerMap.isEmpty()) {
+        PlatformBufferMap::iterator end = m_bufferMarkedForDeletion.end();
+        PlatformBufferMap::iterator it;
+        for (it = m_bufferMarkedForDeletion.begin(); it != end; ++it) {
+            PlatformListenerMap::iterator i = m_listenerMap.find(it->first);
+            if (i != m_listenerMap.end()) {
+                i->second->bufferDestroyed();
+                m_listenerMap.remove(i);
+            }
+
+            PlatformBufferMap::iterator d = m_dirtyBufferMap.find(it->first);
+             if (d != m_dirtyBufferMap.end())
+                 m_dirtyBufferMap.remove(d);
+
+             delete it->second;
+        }
+    }
+
+    m_bufferMarkedForDeletion.clear();
+}
+
+void WaylandCompositor::bufferDestroyed(uint32_t id)
+{
+    if (!m_bufferMap.isEmpty()) {
+        WaylandBuffer* buffer = 0;
+        PlatformBufferMap::iterator it = m_bufferMap.find(id);
+        if (it != m_bufferMap.end()) {
+            m_bufferMarkedForDeletion.add(id, buffer);
+            m_bufferMap.remove(it);
+        }
+    }
+}
+
+WaylandBuffer* WaylandCompositor::mapBuffer(WaylandSurfaceId id, WaylandBufferListener* listener, bool useLinearFilter)
+{
+    cleanUpBufferMap();
+
+    if (m_bufferMap.isEmpty()) {
+        LOG_ERROR("No Wayland Surface available.");
+        return 0;
+    }
+
+    WaylandBuffer* buffer = 0;
+    PlatformBufferMap::iterator it = m_bufferMap.find(id);
+    if (it != m_bufferMap.end())
+        buffer = it->second;
+
+    if (!buffer) {
+        LOG_ERROR("Trying to map an invalid surface.");
+        return 0;
+    }
+
+
+    if (!m_listenerMap.isEmpty()) {
+        PlatformListenerMap::iterator i = m_listenerMap.find(id);
+        if (i != m_listenerMap.end()) {
+            if (listener != i->second)
+                LOG_ERROR("Trying to map surface to a buffer already in use.");
+
+            return buffer;
+        }
+    }
+
+    buffer->mapSurface(useLinearFilter);
+    m_listenerMap.add(id, listener);
+    return buffer;
+}
+
+void WaylandCompositor::unMapBuffer(WaylandSurfaceId id, WaylandBufferListener* listener)
+{
+    if (m_listenerMap.isEmpty())
+        return;
+
+    PlatformListenerMap::iterator i = m_listenerMap.find(id);
+
+    if (i == m_listenerMap.end() || listener != i->second)
+        return;
+
+    m_listenerMap.remove(id);
+
+    if (!m_bufferMap.isEmpty()) {
+        WaylandBuffer* buffer = 0;
+        PlatformBufferMap::iterator it = m_bufferMap.find(id);
+        if (it != m_bufferMap.end()) {
+            buffer = it->second;
+            if (buffer)
+                buffer->unmapSurface();
+        }
+    }
+
+    cleanUpBufferMap();
+}
+
+void WaylandCompositor::addBufferToPendingQueue(WaylandBuffer* buffer)
+{
+    PlatformBufferMap::iterator it = m_dirtyBufferMap.find(buffer->handle());
+    if (it == m_dirtyBufferMap.end())
+        m_dirtyBufferMap.add(buffer->handle(), buffer);
+}
+
+void WaylandCompositor::flush()
+{
+    if (m_dirtyBufferMap.isEmpty())
+        return;
+
+    PlatformBufferMap::iterator end = m_dirtyBufferMap.end();
+    PlatformBufferMap::iterator it;
+    for (it = m_dirtyBufferMap.begin(); it != end; ++it)
+        it->second->handleSurfaceCommit();
+
+    m_dirtyBufferMap.clear();
+}
+
+void WaylandCompositor::prepareForEventHandling()
+{
+    m_time = 0;
+    struct timeval currenTime;
+    int ret = gettimeofday(&currenTime, 0);
+    if (!ret)
+        m_time = currenTime.tv_sec*1000 + currenTime.tv_usec / 1000;
+}
+
+void WaylandCompositor::compositorBind(wl_client* client, void* data, uint32_t version, uint32_t id)
+{
+    WaylandCompositor* compositor = static_cast<WaylandCompositor*>(data);
+    struct wl_resource* resource = wl_resource_create(client, &wl_compositor_interface, std::min(static_cast<int>(version), 3), id);
+    wl_resource_set_implementation(resource, &compositorInterface, compositor, 0);
+}
+
+void WaylandCompositor::compositorCreateSurface(wl_client* client, wl_resource* resource, uint32_t id)
+{
+    WaylandCompositor* compositor = static_cast<WaylandCompositor*>(resource->data);
+    WaylandBuffer* buffer = new WaylandBuffer(client, id);
+    if (!buffer) {
+        wl_resource_post_no_memory(resource);
+        return;
+    }
+
+    compositor->m_bufferMap.add(buffer->handle(), buffer);
+}
+
+void WaylandCompositor::compositorCreateRegion(wl_client*, struct wl_resource*, uint32_t)
+{
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandCompositor.h
new file mode 100644 (file)
index 0000000..43039f2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandCompositor_h
+#define WaylandCompositor_h
+
+#include "GLDefs.h"
+#include "WaylandDisplay.h"
+#include <wayland-client.h>
+#include <wayland-server.h>
+
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class WaylandBuffer;
+
+class WaylandCompositor {
+public:
+    void bufferDestroyed(uint32_t);
+    WaylandBuffer* mapBuffer(WaylandSurfaceId, WaylandBufferListener*, bool);
+    void unMapBuffer(WaylandSurfaceId, WaylandBufferListener*);
+    bool hasPendingEvents() const { return !m_dirtyBufferMap.isEmpty(); }
+    void prepareForEventHandling();
+    void flush();
+
+    static WaylandCompositor* initialize(wl_display*, wl_display*);
+    // Ownership is not transferred to the caller.
+    static WaylandCompositor* getInstance();
+    static void release();
+
+    // Call back functions.
+    static void compositorBind(wl_client*, void*, uint32_t, uint32_t);
+    static void compositorCreateRegion(wl_client*, struct wl_resource*, uint32_t);
+    static void compositorCreateSurface(wl_client*, wl_resource*, uint32_t);
+protected:
+    WaylandCompositor(wl_display*, wl_display*);
+    virtual ~WaylandCompositor();
+private:
+    static WaylandCompositor* m_instance;
+    void cleanUpBufferMap();
+    void addBufferToPendingQueue(WaylandBuffer*);
+    // Map Id and WaylandBuffer
+    typedef HashMap<WaylandSurfaceId, WaylandBuffer*> PlatformBufferMap;
+    PlatformBufferMap m_bufferMap;
+    PlatformBufferMap m_bufferMarkedForDeletion;
+    PlatformBufferMap m_dirtyBufferMap;
+
+    // Map Id and WaylandBufferListener
+    typedef HashMap<WaylandSurfaceId, WaylandBufferListener*> PlatformListenerMap;
+    PlatformListenerMap m_listenerMap;
+    uint32_t m_time;
+    wl_global* m_global;
+    wl_display* m_nestedDisplay;
+    PlatformDisplay m_eglDisplay;
+    OwnPtr<Mutex> m_threadMutex;
+    friend class WaylandBuffer;
+};
+
+}
+
+#endif
+
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.cpp
new file mode 100644 (file)
index 0000000..b1e0a0e
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandDisplay.h"
+
+#include "WaylandCompositor.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+
+// os-compatibility
+extern "C" {
+int osEpollCreateCloExec(void);
+
+static int setCloExecOrClose(int fd)
+{
+    long flags;
+
+    if (fd == -1)
+        return -1;
+
+    flags = fcntl(fd, F_GETFD);
+    if (flags == -1)
+        goto err;
+
+    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+        goto err;
+
+    return fd;
+
+err:
+    close(fd);
+    return -1;
+}
+
+int osEpollCreateCloExec(void)
+{
+    int fd;
+
+#ifdef EPOLL_CLOEXEC
+    fd = epoll_create1(EPOLL_CLOEXEC);
+    if (fd >= 0)
+        return fd;
+    if (errno != EINVAL)
+        return -1;
+#endif
+
+    fd = epoll_create(1);
+    return setCloExecOrClose(fd);
+}
+
+} // os-compatibility
+
+namespace WebCore {
+
+WaylandDisplay* WaylandDisplay::m_instance = 0;
+static int MAXEVENTS = 64;
+
+static const struct wl_registry_listener registrylistener = {
+    WaylandDisplay::handleGlobal,
+    WaylandDisplay::handleGlobalRemove
+};
+
+static const struct wl_callback_listener syncListener = {
+    WaylandDisplay::syncCallback
+};
+
+bool WaylandDisplay::connect(wl_display* display)
+{
+    if (!m_instance)
+        m_instance = openStaticConnection();
+
+    if (display) {
+        if (m_instance && m_instance->m_eventDispatcher)
+            return m_instance->m_eventDispatcher->isRunning();
+
+        m_instance->initialize(display);
+
+        if (m_instance && !m_instance->m_eventDispatcher->isRunning()) {
+            LOG_ERROR("Failed to initialize WaylandDisplay.");
+            return 0;
+        }
+
+    } else {
+        if (m_instance && m_instance->m_queue)
+            return 1;
+
+        m_instance->initialize(display);
+
+        if (m_instance && !m_instance->m_queue) {
+            LOG_ERROR("Failed to initialize WaylandDisplay.");
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+WaylandDisplay* WaylandDisplay::instance()
+{
+    return m_instance;
+}
+
+void WaylandDisplay::disconnect()
+{
+    if (m_instance)
+        m_instance->terminate();
+}
+
+WaylandDisplay* WaylandDisplay::openStaticConnection()
+{
+    static WaylandDisplay display;
+    return &display;
+}
+
+PassOwnPtr<WaylandPollThread> WaylandPollThread::create()
+{
+    OwnPtr<WaylandPollThread> thread = adoptPtr(new WaylandPollThread());
+    if (thread.get() && thread->m_epollFd)
+        return thread.release();
+
+    return nullptr;
+}
+
+WaylandPollThread::WaylandPollThread()
+    : m_display(0)
+    , m_clientDisplay(0)
+    , m_threadId(0)
+    , m_isRunning(false)
+    , m_isLocked(false)
+{
+    m_epollFd = osEpollCreateCloExec();
+}
+
+WaylandPollThread::~WaylandPollThread()
+{
+    ASSERT(isMainThread());
+    terminate();
+    ASSERT(!m_threadId);
+}
+
+void WaylandPollThread::terminate()
+{
+    ASSERT(isMainThread());
+    if (!m_display)
+        return;
+
+    lock();
+    m_isRunning = false;
+    unlock();
+
+    if (m_threadId) {
+        detachThread(m_threadId);
+        m_threadId = 0;
+    }
+
+    if (m_clientDisplay)
+        cancelCallOnMainThread(handleMainEventQueue, this);
+
+    if (m_epollFd) {
+        close(m_epollFd);
+        m_epollFd = 0;
+    }
+
+    m_display = 0;
+    m_clientDisplay = 0;
+}
+
+bool WaylandPollThread::createAndWatchFd()
+{
+    int fd = 0;
+
+    wl_event_loop* loop = wl_display_get_event_loop(m_display);
+    if (!loop) {
+        LOG_ERROR("WaylandPollThread initialization failed: Failed to initialize event loop.");
+        return 0;
+    }
+
+    fd = wl_event_loop_get_fd(loop);
+
+    if (fd < 0) {
+        LOG_ERROR("WaylandPollThread initialization failed: Cannot listen to current fd.");
+        return 0;
+    }
+
+    struct epoll_event ep;
+    ep.events = EPOLLIN;
+    ep.data.ptr = 0;
+    epoll_ctl(m_epollFd, EPOLL_CTL_ADD, fd, &ep);
+    return 1;
+}
+
+void WaylandPollThread::start(wl_display* display, wl_display* clientDisplay)
+{
+    m_isRunning = false;
+    if (m_threadId)
+        terminate();
+
+    m_display = display;
+    m_clientDisplay = clientDisplay;
+
+    if (!createAndWatchFd()) {
+        terminate();
+        return;
+    }
+
+    // Start worker thread.
+    if (!m_threadId) {
+        m_isRunning = true;
+
+        m_threadCreationMutex = adoptPtr(new Mutex);
+        // Start worker thread.
+        MutexLocker lock(*m_threadCreationMutex.get());
+        m_threadId = createThread(WaylandPollThread::threadEntry, this, "WaylandPoll.Thread");
+        m_threadMutex = adoptPtr(new Mutex);
+    }
+}
+
+void WaylandPollThread::handleMainEventQueue(void* context)
+{
+    WaylandPollThread* thread = static_cast<WaylandPollThread*>(context);
+    thread->flushClientDisplay();
+    WaylandCompositor* compositor = WaylandCompositor::getInstance();
+    if (compositor && compositor->hasPendingEvents()) {
+        ScopedDisplayLocker lock(thread);
+        compositor->flush();
+    }
+}
+
+void WaylandPollThread::flushClientDisplay()
+{
+    int i = 1;
+    while (i > 0)
+        i = wl_display_dispatch_pending(m_clientDisplay);
+
+    wl_display_flush(m_clientDisplay);
+}
+
+void WaylandPollThread::stop()
+{
+    terminate();
+}
+
+bool WaylandPollThread::lock()
+{
+    if (m_isLocked)
+        return false;
+
+    if (!m_threadMutex->tryLock())
+        return false;
+
+    m_isLocked = true;
+    return true;
+}
+
+void WaylandPollThread::unlock()
+{
+    if (m_isLocked) {
+        m_threadMutex->unlock();
+        m_isLocked = false;
+    }
+}
+
+void WaylandPollThread::threadEntry(void* threadData)
+{
+    ASSERT(threadData);
+    WaylandPollThread* handler = reinterpret_cast<WaylandPollThread*>(threadData);
+    handler->pollEventLoop();
+}
+
+int WaylandPollThread::pollEventLoop()
+{
+    // Wait for until we have m_threadId established before starting the run loop.
+    MutexLocker lock(*m_threadCreationMutex.get());
+    ASSERT(!isMainThread());
+
+    epoll_event ep[MAXEVENTS];
+    int i, ret, count = 0;
+    bool flushClient = false;
+    wl_event_loop* loop = wl_display_get_event_loop(m_display);
+    // Keep running tasks until we're killed.
+    while (m_isRunning) {
+        count = epoll_wait(m_epollFd, ep, MAXEVENTS, -1);
+
+        if (count >0 && m_isRunning) {
+
+            for (i = 0; i < count; i++) {
+                if (ep[i].events & EPOLLIN) {
+                    flushClient = true;
+                    break;
+                }
+            }
+
+            if (flushClient) {
+                flushClient = false;
+                m_threadMutex->lock();
+                WaylandCompositor* compositor = WaylandCompositor::getInstance();
+                if (compositor)
+                    compositor->prepareForEventHandling();
+
+                ret = wl_event_loop_dispatch(loop, 0);
+                if (ret == -1)
+                    LOG_ERROR("WaylandDisplay Error: wl_event_loop_dispatch error %d \n", ret);
+
+                wl_display_flush_clients(m_display);
+                m_threadMutex->unlock();
+                callOnMainThread(WaylandPollThread::handleMainEventQueue, this);
+            }
+        }
+    }
+
+    return 0;
+}
+
+WaylandDisplay::WaylandDisplay()
+    : m_display(0)
+    , m_compositor(0)
+    , m_registry(0)
+    , m_wlCompositor(0)
+    , m_queue(0)
+{
+}
+
+void WaylandDisplay::initialize(wl_display* display)
+{
+
+    if (display) {
+        m_eventDispatcher = WaylandPollThread::create();
+        m_display = wl_display_create();
+        if (!m_display) {
+            LOG_ERROR("WaylandDisplay initialization failed:: Failed to make connection with Wayland for client display.");
+            terminate();
+            return;
+        }
+
+        String socketString("Wayland-");
+        socketString.append(String::format("%d", m_eventDispatcher->id()));
+        setenv("WAYLAND_NESTED_CLIENT", socketString.utf8().data(), 1);
+
+        if (wl_display_add_socket(m_display, socketString.utf8().data())) {
+            LOG_ERROR("WaylandDisplay initialization failed:: Failed to Add socket.");
+            terminate();
+            return;
+        }
+
+        m_compositor = WaylandCompositor::initialize(display, m_display);
+        if (!m_compositor) {
+            LOG_ERROR("WaylandDisplay initialization failed: Compositor initialization failed.");
+            terminate();
+            return;
+        }
+
+        m_eventDispatcher->start(m_display, display);
+
+    } else {
+        const char* nestedSocket = getenv("WAYLAND_NESTED_CLIENT");
+        m_display = wl_display_connect(nestedSocket);
+
+        if (!m_display) {
+            LOG_ERROR("WaylandDisplay initialization failed: Failed to make connection with Wayland.");
+            terminate();
+            return;
+        }
+
+        m_registry = wl_display_get_registry(m_display);
+        wl_registry_add_listener(m_registry, &registrylistener, this);
+
+        if (wl_display_roundtrip(m_display) < 0) {
+            LOG_ERROR("WaylandDisplay initialization failed: Failed to process Wayland connection.");
+            terminate();
+            return;
+        }
+
+        m_queue = wl_display_create_queue(m_display);
+        wl_proxy_set_queue((struct wl_proxy *)m_registry, m_queue);
+    }
+}
+
+WaylandDisplay::~WaylandDisplay()
+{
+    terminate();
+}
+
+void WaylandDisplay::terminate()
+{
+    if (m_eventDispatcher) {
+        m_eventDispatcher->stop();
+        m_eventDispatcher = nullptr;
+    }
+
+    if (m_compositor) {
+        m_compositor->release();
+        m_compositor = 0;
+    }
+
+    if (m_registry) {
+        wl_registry_destroy(m_registry);
+        m_registry = 0;
+
+        if (m_display) {
+            wl_display_flush(m_display);
+            wl_display_disconnect(m_display);
+            m_display = 0;
+        }
+    }
+
+    m_instance = 0;
+    m_display = 0;
+}
+
+struct wl_display* WaylandDisplay::nativeDisplay()
+{
+    wl_display* wlDisplay = 0;
+    if (m_instance)
+        wlDisplay = m_instance->m_display;
+
+    return wlDisplay;
+}
+
+struct wl_compositor* WaylandDisplay::compositor()
+{
+    struct wl_compositor* wlCompositor = 0;
+    if (m_instance)
+        wlCompositor = m_instance->m_wlCompositor;
+
+    return wlCompositor;
+}
+
+struct wl_registry* WaylandDisplay::registry()
+{
+    struct wl_registry* wlRegistry = 0;
+    if (m_instance)
+        wlRegistry = m_instance->m_registry;
+
+    return wlRegistry;
+}
+
+WaylandBuffer* WaylandDisplay::mapBuffer(WaylandSurfaceId sharedBufferId, WaylandBufferListener* listener, bool useLinearFilter)
+{
+    if (m_compositor && m_eventDispatcher) {
+        ScopedDisplayLocker lock(m_eventDispatcher.get());
+        return m_compositor->mapBuffer(sharedBufferId, listener, useLinearFilter);
+    }
+
+    return 0;
+}
+
+void WaylandDisplay::unMapBuffer(WaylandSurfaceId id, WaylandBufferListener* listener)
+{
+    if (m_compositor && m_eventDispatcher) {
+        ScopedDisplayLocker lock(m_eventDispatcher.get());
+        m_compositor->unMapBuffer(id, listener);
+    }
+}
+
+PassOwnPtr<WaylandSurface> WaylandDisplay::createSurface()
+{
+    if (!m_wlCompositor)
+        return nullptr;
+
+    OwnPtr<WaylandSurface> surface = adoptPtr(new WaylandSurface(m_wlCompositor));
+    if (surface && surface->wlSurface())
+        return surface.release();
+
+    return nullptr;
+}
+
+void WaylandDisplay::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t)
+{
+    WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
+    if (display && !strcmp(interface, "wl_compositor"))
+        display->m_wlCompositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
+}
+
+void WaylandDisplay::handleGlobalRemove(void*, struct wl_registry*, uint32_t)
+{
+}
+
+void WaylandDisplay::syncCallback(void *data, struct wl_callback *callback, uint32_t serial)
+{
+    int* done = static_cast<int*>(data);
+    *done = 1;
+    wl_callback_destroy(callback);
+}
+
+int WaylandDisplay::syncDisplay()
+{
+    if (!m_queue)
+        return -1;
+
+    int done = 0, ret = 0;
+    struct wl_callback* callback = wl_display_sync(m_display);
+    wl_callback_add_listener(callback, &syncListener, &done);
+    wl_proxy_set_queue((struct wl_proxy *) callback, m_queue);
+    while (ret != -1 && !done)
+        ret = wl_display_dispatch_queue(m_display, m_queue);
+
+    wl_display_dispatch_pending(m_display);
+
+    return ret;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.h
new file mode 100644 (file)
index 0000000..103b883
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandDisplay_h
+#define WaylandDisplay_h
+
+#include "WaylandHelper.h"
+#include "WaylandSurface.h"
+
+namespace WebCore {
+class WaylandBuffer;
+
+class WaylandBufferListener {
+public:
+    virtual void bufferDestroyed() = 0;
+};
+
+class WaylandDisplay {
+public:
+    static bool connect(wl_display* = 0);
+    // Ownership is not transferred.
+    static WaylandDisplay* instance();
+    static void disconnect();
+    // client apis.
+    struct wl_display* nativeDisplay();
+    struct wl_compositor* compositor();
+    struct wl_registry* registry();
+    int syncDisplay();
+    // Ownership is transferred.
+    PassOwnPtr<WaylandSurface> createSurface();
+
+    // Ownership is not transferred.
+    WaylandBuffer* mapBuffer(WaylandSurfaceId, WaylandBufferListener*, bool);
+    void unMapBuffer(WaylandSurfaceId, WaylandBufferListener*);
+
+    // Used for registration purpose only.
+    static void handleGlobal(void*, struct wl_registry*, uint32_t, const char*, uint32_t);
+    static void handleGlobalRemove(void*, struct wl_registry*, uint32_t);
+
+    // callback handlers.
+    static void syncCallback(void*, struct wl_callback*, uint32_t);
+
+protected:
+    WaylandDisplay();
+    virtual ~WaylandDisplay();
+
+private:
+    void terminate();
+    void initialize(wl_display* = 0);
+    static WaylandDisplay* openStaticConnection();
+
+    // Display
+    wl_display* m_display;
+
+    // Thread
+    OwnPtr<WaylandPollThread> m_eventDispatcher;
+
+    // Intance
+    static WaylandDisplay* m_instance;
+
+    // Compositor
+    WaylandCompositor* m_compositor;
+
+    // wl registry
+    struct wl_registry* m_registry;
+    struct wl_compositor* m_wlCompositor;
+    struct wl_event_queue* m_queue;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandHelper.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandHelper.cpp
deleted file mode 100644 (file)
index d5898f8..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WaylandHelper.h"
-
-#include <string.h>
-
-namespace WebCore {
-struct wl_compositor* WaylandHelper::m_compositor = 0;
-
-static const struct wl_registry_listener registrylistener = {
-    WaylandHelper::handleGlobal,
-    WaylandHelper::handleGlobalRemove
-};
-
-struct DisplayConnection {
-    DisplayConnection()
-        : m_display(0)
-        , m_registry(0)
-    {
-        m_display = wl_display_connect(0);
-        if (!m_display) {
-            LOG_ERROR("Failed to make connection with Wayland.");
-            return;
-        }
-
-        m_registry = wl_display_get_registry(m_display);
-        wl_registry_add_listener(m_registry, &registrylistener, 0);
-
-        if (wl_display_roundtrip(m_display) < 0) {
-            LOG_ERROR("Failed to process Wayland connection.");
-            close();
-        }
-    }
-
-    ~DisplayConnection()
-    {
-        close();
-    }
-
-    struct wl_display* display() const { return m_display; }
-
-private:
-    void close()
-    {
-        if (m_registry) {
-            wl_registry_destroy(m_registry);
-            m_registry = 0;
-        }
-
-        if (m_display) {
-            wl_display_flush(m_display);
-            wl_display_disconnect(m_display);
-            m_display = 0;
-        }
-    }
-
-    struct wl_display* m_display;
-    struct wl_registry* m_registry;
-};
-
-struct wl_display* WaylandHelper::nativeDisplay()
-{
-    // Display connection will only be broken at program shutdown.
-    static DisplayConnection displayConnection;
-    return displayConnection.display();
-}
-
-void WaylandHelper::handleGlobal(void*, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t)
-{
-    if (!strcmp(interface, "wl_compositor"))
-        m_compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
-}
-
-void WaylandHelper::handleGlobalRemove(void*, struct wl_registry*, uint32_t)
-{
-}
-
-}
index 4a920bf..d745f08 100644 (file)
 
 #include <wayland-client.h>
 #include <wayland-egl.h>
+#include <wayland-server.h>
+
+#include <wtf/MainThread.h>
+#include <wtf/MessageQueue.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Threading.h>
+#include <wtf/threads/BinarySemaphore.h>
 
 namespace WebCore {
+class WaylandDisplay;
+class ScopedDisplayLocker;
 
-class WaylandHelper {
+// To be only used internally by WaylandDisplay.
+class WaylandPollThread {
 public:
-    static struct wl_display* nativeDisplay();
-    static struct wl_compositor* compositor() { return m_compositor; }
+    // Call Baack
+    static void handleMainEventQueue(void*);
+    virtual ~WaylandPollThread();
 
-    // Used for registration purpose only.
-    static void handleGlobal(void*, struct wl_registry*, uint32_t, const char*, uint32_t);
-    static void handleGlobalRemove(void*, struct wl_registry*, uint32_t);
 private:
-    static struct wl_compositor* m_compositor;
+    static PassOwnPtr<WaylandPollThread> create();
+    void start(wl_display*, wl_display*);
+    void stop();
+    bool isRunning() { return m_isRunning; }
+    void flushClientDisplay();
+    bool lock();
+    void unlock();
+    int id() const { return m_epollFd; }
+
+    WaylandPollThread();
+    void terminate();
+    bool createAndWatchFd();
+    static void threadEntry(void*);
+    int pollEventLoop();
+    wl_display* m_display;
+    wl_display* m_clientDisplay;
+
+    // Thread
+    ThreadIdentifier m_threadId;
+    OwnPtr<Mutex> m_threadCreationMutex;
+    OwnPtr<Mutex> m_threadMutex;
+    int m_epollFd;
+    bool m_isRunning :1;
+    bool m_isLocked :1;
+    friend class WaylandDisplay;
+    friend class ScopedDisplayLocker;
+};
+
+class ScopedDisplayLocker {
+public:
+    ScopedDisplayLocker(WaylandPollThread* thread) : m_thread(thread)
+    {
+        bool lockedDisplay = false;
+        // Aquire lock.
+        while (!lockedDisplay)
+            lockedDisplay = m_thread->lock();
+    }
+
+    ~ScopedDisplayLocker()
+    {
+        m_thread->unlock();
+    }
+
+private:
+    ScopedDisplayLocker(const ScopedDisplayLocker&);
+    ScopedDisplayLocker& operator=(const ScopedDisplayLocker&);
+    static void* operator new (size_t);
+    static void operator delete (void*);
+    WaylandPollThread* m_thread;
 };
 
 }
 #endif
+
+
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.cpp
new file mode 100644 (file)
index 0000000..007f0e1
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandSurface.h"
+
+#include "EGLHelper.h"
+#include "GLPlatformContext.h"
+#include "WaylandCompositor.h"
+#include "WaylandDisplay.h"
+
+namespace WebCore {
+static const struct wl_callback_listener frameListener = {
+    WaylandSurface::surfaceFrameCallback
+};
+
+static const struct wl_surface_interface surfaceInterface = {
+    WaylandBuffer::surfaceDestroy,
+    WaylandBuffer::surfaceAttach,
+    WaylandBuffer::surfaceDamage,
+    WaylandBuffer::surfaceFrame,
+    WaylandBuffer::surfaceSetOpaqueRegion,
+    WaylandBuffer::surfaceSetInputRegion,
+    WaylandBuffer::surfaceCommit,
+    WaylandBuffer::surfaceSetBufferTransform,
+    WaylandBuffer::surfaceSetBufferScale
+};
+
+WaylandSurface::WaylandSurface(struct wl_compositor* compositor)
+    : m_surface(0)
+    , m_frameCallBack(0)
+    , m_queue(0)
+    , m_id(0)
+{
+    static WaylandSurfaceId bufferHandleId = 0;
+    m_surface = wl_compositor_create_surface(compositor);
+
+    if (!m_surface) {
+        LOG_ERROR("WaylandSurface: Failed to create surface.");
+        return;
+    }
+
+    bufferHandleId++;
+    m_id = bufferHandleId;
+    m_queue = wl_display_create_queue(WaylandDisplay::instance()->nativeDisplay());
+    wl_proxy_set_queue((struct wl_proxy *)WaylandDisplay::instance()->registry(), m_queue);
+}
+
+void WaylandSurface::addFrameCallBack()
+{
+    if (m_frameCallBack)
+        return;
+
+    if (!m_queue) {
+        m_queue = wl_display_create_queue(WaylandDisplay::instance()->nativeDisplay());
+        wl_proxy_set_queue((struct wl_proxy *)WaylandDisplay::instance()->registry(), m_queue);
+    }
+
+    m_frameCallBack = wl_surface_frame(m_surface);
+    wl_callback_add_listener(m_frameCallBack, &frameListener, this);
+    wl_proxy_set_queue((struct wl_proxy *)m_frameCallBack, m_queue);
+}
+
+void WaylandSurface::deleteFrameCallBack()
+{
+    if (m_frameCallBack) {
+        wl_callback_destroy(m_frameCallBack);
+        m_frameCallBack = 0;
+    }
+
+    if (m_queue) {
+        wl_event_queue_destroy(m_queue);
+        m_queue = 0;
+    }
+}
+
+int WaylandSurface::ensureFrameCallBackDone()
+{
+    int ret = 0;
+    if (m_frameCallBack) {
+        while (m_frameCallBack && ret != -1)
+            ret = wl_display_dispatch_queue(WaylandDisplay::instance()->nativeDisplay(), m_queue);
+
+        wl_display_dispatch_pending(WaylandDisplay::instance()->nativeDisplay());
+    }
+
+    return ret;
+}
+
+void WaylandSurface::surfaceFrameCallback(void* data, struct wl_callback* callback, uint32_t)
+{
+    WaylandSurface* surface = static_cast<WaylandSurface *>(data);
+    wl_callback_destroy(callback);
+    surface->destroyFrameCallBack();
+}
+
+void WaylandSurface::destroyFrameCallBack()
+{
+    m_frameCallBack = 0;
+}
+
+WaylandSurface::~WaylandSurface()
+{
+    m_id = 0;
+    deleteFrameCallBack();
+
+    if (m_surface) {
+        wl_surface_destroy(m_surface);
+        m_surface = 0;
+    }
+}
+
+WaylandBuffer::WaylandBuffer(wl_client* client, uint32_t id)
+    : m_bufferResource(0)
+    , m_commitedResource(0)
+    , m_useLinearFilter(false)
+    , m_state(Default)
+    , m_id(0)
+    , m_textureId(0)
+{
+    static WaylandSurfaceId bufferHandleId = 0;
+    bufferHandleId++;
+    m_id = bufferHandleId;
+    wl_resource* resource = wl_resource_create(client, &wl_surface_interface, 1, id);
+    wl_resource_set_implementation(resource, &surfaceInterface, this, WaylandBuffer::destroySurface);
+    wl_list_init(&m_callbackList);
+}
+
+WaylandBuffer::~WaylandBuffer()
+{
+    unmapSurface();
+    m_id = 0;
+}
+
+uint WaylandBuffer::textureId()
+{
+    if (m_state & PendingUpdate)
+        bindTextureToImage();
+
+    return m_textureId;
+}
+
+void WaylandBuffer::mapSurface(bool useLinearFilter)
+{
+    if ((m_state & Destroyed) || (m_state & Mapped))
+        return;
+
+    m_state |= Mapped;
+    m_useLinearFilter = useLinearFilter;
+    if (!m_textureId)
+        m_state |= PendingUpdate;
+}
+
+void WaylandBuffer::unmapSurface()
+{
+    m_state &= ~Mapped;
+    release();
+}
+
+void WaylandBuffer::release()
+{
+    if (m_textureId) {
+        glBindTexture(GL_TEXTURE_2D, 0);
+        glDeleteTextures(1, &m_textureId);
+        m_textureId = 0;
+    }
+}
+
+void WaylandBuffer::attach(wl_resource* bufferResource)
+{
+    if (m_bufferResource == bufferResource)
+        return;
+
+    if (m_bufferResource)
+        wl_buffer_send_release(m_bufferResource);
+
+    m_bufferResource = bufferResource;
+}
+
+void WaylandBuffer::handleSurfaceCommit()
+{
+    m_commitedResource = m_bufferResource;
+
+    if (m_commitedResource)
+        m_state |= PendingUpdate;
+}
+
+void WaylandBuffer::bindTextureToImage()
+{
+    if (!m_commitedResource || (m_state & Destroyed))
+        return;
+
+    m_state &= ~PendingUpdate;
+    EGLDisplay display = WaylandCompositor::getInstance()->m_eglDisplay;
+    EGLImageKHR image;
+    EGLHelper::createEGLImage(&image, EGL_WAYLAND_BUFFER_WL, wl_resource_get_user_data(m_commitedResource), 0, display);
+    if (image == EGL_NO_IMAGE_KHR) {
+        LOG_ERROR("Failed to create EGLImage.");
+        return;
+    }
+
+    if (!m_textureId)
+        glGenTextures(1, &m_textureId);
+
+    glBindTexture(GL_TEXTURE_2D, m_textureId);
+    EGLHelper::imageTargetTexture2DOES(image);
+    updateFilter();
+    EGLHelper::destroyEGLImage(image, display);
+    m_commitedResource = 0;
+}
+
+void WaylandBuffer::updateFilter()
+{
+    GLfloat filter = GL_NEAREST;
+    if (m_useLinearFilter)
+        filter = GL_LINEAR;
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+void WaylandBuffer::surfaceCommitCallBack()
+{
+    struct frameCallback* frameCallback;
+    struct frameCallback* next;
+    bool callbackSent = false;
+
+    uint32_t time = 0;
+    WaylandCompositor* compositor = WaylandCompositor::getInstance();
+    if (compositor)
+        time = compositor->m_time;
+
+    wl_list_for_each_safe(frameCallback, next, &m_callbackList, link)
+    {
+        wl_callback_send_done(frameCallback->resource, time);
+        wl_resource_destroy(frameCallback->resource);
+        callbackSent = true;
+    }
+
+    if (callbackSent)
+        wl_list_init(&m_callbackList);
+}
+
+void WaylandBuffer::destroySurface(wl_resource* resource)
+{
+    WaylandBuffer* buffer = getBuffer(resource);
+    if (!buffer) {
+        LOG_ERROR("Not a valid buffer");
+        return;
+    }
+
+    if (!(buffer->m_state & WaylandBuffer::Destroyed)) {
+        buffer->m_state |= WaylandBuffer::Destroyed;
+        buffer->m_state &= ~WaylandBuffer::Mapped;
+        WaylandCompositor* compositor = WaylandCompositor::getInstance();
+        if (compositor)
+            compositor->bufferDestroyed(buffer->handle());
+    }
+}
+
+void WaylandBuffer::surfaceDestroy(wl_client*, wl_resource* resource)
+{
+    wl_resource_destroy(resource);
+}
+
+WaylandBuffer* WaylandBuffer::getBuffer(wl_resource* resource)
+{
+    return static_cast<WaylandBuffer*>(wl_resource_get_user_data(resource));
+}
+
+void WaylandBuffer::surfaceAttach(wl_client*, wl_resource* resource, wl_resource* buffer_resource, int32_t, int32_t)
+{
+    WaylandBuffer* buffer = getBuffer(resource);
+    buffer->attach(buffer_resource);
+}
+
+void WaylandBuffer::surfaceDamage(wl_client*, wl_resource*, int32_t, int32_t, int32_t, int32_t)
+{
+}
+
+void WaylandBuffer::surfaceFrame(wl_client* client, wl_resource* resource, uint32_t id)
+{
+    WaylandBuffer* buffer = getBuffer(resource);
+    if (!buffer)
+        return;
+
+    struct frameCallback* callback = new frameCallback;
+    if (!callback) {
+        wl_resource_post_no_memory(resource);
+        return;
+    }
+
+    callback->resource = wl_resource_create(client, &wl_callback_interface, 1, id);
+    wl_resource_set_implementation(callback->resource, 0, callback, WaylandBuffer::destroyFrameCallback);
+    wl_list_insert(buffer->m_callbackList.prev, &callback->link);
+}
+
+void WaylandBuffer::surfaceSetOpaqueRegion(wl_client*, wl_resource*, wl_resource*)
+{
+}
+
+void WaylandBuffer::surfaceSetInputRegion(wl_client*, wl_resource*, wl_resource*)
+{
+}
+
+void WaylandBuffer::surfaceCommit(wl_client*, wl_resource* resource)
+{
+    WaylandBuffer* buffer = getBuffer(resource);
+    if (!buffer)
+        return;
+
+    buffer->surfaceCommitCallBack();
+
+    if (!(buffer->m_state & WaylandBuffer::Mapped))
+        return;
+
+    WaylandCompositor* compositor = WaylandCompositor::getInstance();
+    if (compositor)
+        compositor->addBufferToPendingQueue(buffer);
+}
+
+void WaylandBuffer::surfaceSetBufferTransform(struct wl_client *, struct wl_resource *, int)
+{
+}
+
+void WaylandBuffer::surfaceSetBufferScale(struct wl_client*, struct wl_resource*, int32_t)
+{
+}
+
+void WaylandBuffer::destroyFrameCallback(struct wl_resource* resource)
+{
+    struct frameCallback* callback = static_cast<struct frameCallback*>(wl_resource_get_user_data(resource));
+    if (callback) {
+        wl_list_remove(&callback->link);
+        delete callback;
+    }
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandSurface.h
new file mode 100644 (file)
index 0000000..1bcad24
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandSurface_h
+#define WaylandSurface_h
+
+#include <wayland-client.h>
+#include <wayland-server.h>
+
+namespace WebCore {
+class WaylandCompositor;
+class WaylandDisplay;
+
+typedef uint WaylandSurfaceId;
+
+class WaylandSurface {
+public:
+    virtual ~WaylandSurface();
+    struct wl_surface* wlSurface() const { return m_surface; }
+    WaylandSurfaceId handle() const { return m_id; }
+
+    // FrameCallBack.
+    // Example usage to swap buffers
+    // if (m_surface->ensureFrameCallBackDone() == -1)
+    //    return;
+    // m_surface->addFrameCallBack();
+    // Swap buffers.
+    void addFrameCallBack();
+    // Ensure that deleteFrameCallBack is called before
+    // destroying any EGL resources associated with the
+    // surface.
+    // Example usage:
+    // deleteFrameCallBack();
+    // destroy egl window etc
+    // m_surface = nullptr; i.e destroy WaylandSurface.
+    void deleteFrameCallBack();
+    // see addFrameCallBack.
+    int ensureFrameCallBackDone();
+
+    // callback
+    static void surfaceFrameCallback(void*, struct wl_callback*, uint32_t);
+
+private:
+    WaylandSurface(struct wl_compositor*);
+    void destroyFrameCallBack();
+    struct wl_surface* m_surface;
+    struct wl_callback* m_frameCallBack;
+    struct wl_event_queue* m_queue;
+    WaylandSurfaceId m_id;
+    friend class WaylandDisplay;
+};
+
+class WaylandBuffer {
+public:
+    struct frameCallback {
+        struct wl_resource* resource;
+        struct wl_list link;
+    };
+
+    enum State {
+        Default = 0x00,
+        Mapped = 0x01,
+        PendingUpdate = 0x02,
+        Destroyed = 0x04
+    };
+
+    virtual ~WaylandBuffer();
+    typedef unsigned WaylandBufferState;
+    uint handle() const { return m_id; }
+
+    // texture.
+    uint textureId();
+    WaylandBufferState state() const { return m_state; }
+
+    static WaylandBuffer* getBuffer(wl_resource*);
+    static void surfaceDestroy(wl_client*, wl_resource*);
+    static void surfaceAttach(wl_client*, wl_resource*, wl_resource*, int32_t, int32_t);
+    static void surfaceDamage(wl_client*, wl_resource*, int32_t, int32_t, int32_t, int32_t);
+    static void surfaceFrame(wl_client*, wl_resource*, uint32_t);
+    static void surfaceSetOpaqueRegion(wl_client*, wl_resource*, wl_resource*);
+    static void surfaceSetInputRegion(wl_client*, wl_resource*, wl_resource*);
+    static void surfaceCommit(wl_client*, wl_resource*);
+    static void surfaceSetBufferTransform(struct wl_client*, struct wl_resource *, int);
+    static void destroySurface(wl_resource*);
+    static void surfaceSetBufferScale(struct wl_client*, struct wl_resource*, int32_t);
+    static void destroyFrameCallback(struct wl_resource*);
+private:
+    WaylandBuffer(wl_client*, uint32_t);
+    void mapSurface(bool);
+    void unmapSurface();
+    void attach(wl_resource*);
+    void surfaceCommitCallBack();
+    void handleSurfaceCommit();
+    void release();
+    void updateFilter();
+    void bindTextureToImage();
+    struct wl_resource* m_bufferResource;
+    struct wl_resource* m_commitedResource;
+    struct wl_list m_callbackList;
+    bool m_useLinearFilter :1;
+    WaylandBufferState m_state :6;
+    uint m_id;
+    uint32_t m_textureId;
+    friend class WaylandCompositor;
+};
+
+}
+
+#endif
index 6ba852b..824f019 100755 (executable)
@@ -55,6 +55,7 @@ void TextureMapperSurfaceBackingStore::setGraphicsSurface(uint64_t graphicsSurfa
         m_graphicsSurfaceSize = surfaceSize;
     }
 
+#if !PLATFORM(WAYLAND)
     RefPtr<WebCore::GraphicsSurface> surface = graphicsSurface();
     if (surface && surface->frontBuffer() != frontBuffer)
 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
@@ -62,6 +63,7 @@ void TextureMapperSurfaceBackingStore::setGraphicsSurface(uint64_t graphicsSurfa
 #else
         surface->swapBuffers();
 #endif
+#endif
 }
 
 PassRefPtr<BitmapTexture> TextureMapperSurfaceBackingStore::texture() const
index f587d32..a9bbd98 100755 (executable)
@@ -914,7 +914,11 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co
 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
 PassRefPtr<PlatformSurfaceTexture> TextureMapperGL::createPlatformSurfaceTexture(int platformSurfaceID, IntSize size, bool useLinearFilter)
 {
+#if PLATFORM(WAYLAND)
+    PlatformTextureWayland* texture = new PlatformTextureWayland(platformSurfaceID, size);
+#else
     PlatformSurfaceTextureGL* texture = new PlatformSurfaceTextureGL(platformSurfaceID, size);
+#endif
     texture->initialize(useLinearFilter);
     return adoptRef(texture);
 }
index b37b8b6..1bb6864 100755 (executable)
 #include "TransformationMatrix.h"
 
 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
+#if PLATFORM(WAYLAND)
+#include "PlatformTextureWayland.h"
+#else
 #include "PlatformSurfaceTextureGL.h"
 #endif
+#endif
 
 #if USE(TIZEN_TEXTURE_MAPPER)
 // FIXME
index a8604a0..89f70f9 100755 (executable)
@@ -34,6 +34,12 @@ LIST(APPEND WebKit2StaticForDebug_INCLUDE_DIRECTORIES
     ${UIGadget_INCLUDE_DIRS}
 )
 
+IF (WTF_PLATFORM_WAYLAND)
+    LIST(APPEND WebKit2StaticForDebug_INCLUDE_DIRECTORIES
+        "${WEBCORE_DIR}/platform/graphics/surfaces/wayland"
+    )
+ENDIF()
+
 IF (ENABLE_PLUGIN_PROCESS)
     LIST(APPEND PluginProcess_LIBRARIES
         ${GLES20_LIBRARIES}
index 186a77d..2a3accc 100755 (executable)
 #include "ScreenReaderProxy.h"
 #endif
 
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && PLATFORM(WAYLAND)
+#include "Evas_Engine_Wayland_Egl.h"
+#include "WaylandDisplay.h"
+#endif
+
 using namespace WebCore;
 using namespace std;
 
@@ -1449,10 +1454,17 @@ PageClientEvasGL::PageClientEvasGL(EwkViewImpl* viewImpl)
     , m_isAcceleratedCompositingModeInitialized(false)
 {
     initializeAcceleratedCompositingMode();
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && PLATFORM(WAYLAND)
+    Evas_Engine_Info_Wayland_Egl* einfo = (Evas_Engine_Info_Wayland_Egl*)evas_engine_info_get(evas_object_evas_get(m_viewImpl->view()));
+    WaylandDisplay::connect(einfo->info.display);
+#endif
 }
 
 PageClientEvasGL::~PageClientEvasGL()
 {
+#if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE) && PLATFORM(WAYLAND)
+    WaylandDisplay::disconnect();
+#endif
     if (m_viewImpl && m_viewImpl->page())
         m_viewImpl->page()->close();
 }