7cd6452f13476da53397242eb6adf951efbde903
[profile/ivi/layer-management.git] / LayerManagerPlugins / Renderers / Graphic / src / TextureBinders / X11EglImage.cpp
1 /***************************************************************************
2 *
3 * Copyright 2010,2011 BMW Car IT GmbH
4 *
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *        http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19
20 #include "TextureBinders/X11EglImage.h"
21 #include "X11/extensions/Xcomposite.h"
22 #include <EGL/egl.h>
23 #include <EGL/eglext.h>
24 #include <GLES2/gl2ext.h>
25 #include "PlatformSurfaces/EglXPlatformSurface.h"
26 #include "Log.h"
27
28 X11EglImage::X11EglImage(EGLDisplay eglDisplay, Display* x11display)
29 : m_eglDisplay(eglDisplay)
30 , m_x11display(x11display)
31 {
32     // pseudo require EGL to have been initialised
33     // we dont really need the EGL handle as such
34
35     m_pfGLEglImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
36     m_pfEglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
37     m_pfEglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
38
39     if (!m_pfEglCreateImageKHR || !m_pfEglDestroyImageKHR || !m_pfGLEglImageTargetTexture2DOES)
40     {
41         LOG_ERROR("X11EglImage", "Query EGL Extensions failed");
42     }
43 }
44
45 bool X11EglImage::bindSurfaceTexture(Surface* surface)
46 {
47     EglXPlatformSurface* nativeSurface = (EglXPlatformSurface*)surface->platform;
48     if (nativeSurface && nativeSurface->isReadyForRendering())
49     {
50         glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
51         return true;
52     }
53     return false;
54 }
55
56 bool X11EglImage::unbindSurfaceTexture(Surface* surface)
57 {
58     (void)surface; // TODO: remove, only prevents warning
59
60     // TODO
61     return true;
62 }
63
64 void X11EglImage::createClientBuffer(Surface* surface)
65 {
66     LOG_DEBUG("X11EglImage", "creating client buffer with native display: " << m_x11display << " for native handle: " << surface->getNativeContent());
67     EglXPlatformSurface* nativeSurface = (EglXPlatformSurface*)surface->platform;
68     if (NULL != nativeSurface)
69     {
70         Pixmap windowPixmap = 0;
71         windowPixmap = XCompositeNameWindowPixmap(m_x11display, surface->getNativeContent());
72         if (windowPixmap == 0)
73         {
74             LOG_ERROR("X11EglImage", "didnt create pixmap!");
75         }
76         else
77         {
78             nativeSurface->pixmap = windowPixmap;
79         }
80
81         EGLImageKHR eglImage = 0;
82         LOG_DEBUG("X11EglImage", "creating EGL Image from client buffer");
83         if (nativeSurface->eglImage)
84         {
85             m_pfEglDestroyImageKHR(m_eglDisplay, nativeSurface->eglImage);
86             glDeleteTextures(1, &nativeSurface->texture);
87             nativeSurface->eglImage = 0;
88             nativeSurface->texture = 0;
89         }
90         eglImage = m_pfEglCreateImageKHR(m_eglDisplay,
91                                         EGL_NO_CONTEXT,
92                                         EGL_NATIVE_PIXMAP_KHR,
93                                         (EGLClientBuffer)windowPixmap,
94                                         NULL);
95         if (!eglImage)
96         {
97             LOG_DEBUG("X11EglImage", "could not allocate EGL Image for window");
98         }
99         else
100         {
101             nativeSurface->eglImage = eglImage;
102             glGenTextures(1, &nativeSurface->texture);
103             glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
104             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
105             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
106             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
107             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
108             m_pfGLEglImageTargetTexture2DOES(GL_TEXTURE_2D, nativeSurface->eglImage);
109         }
110     }
111 }
112
113 PlatformSurface* X11EglImage::createPlatformSurface(Surface* surface)
114 {
115     return new EglXPlatformSurface(surface);
116 }
117
118 void X11EglImage::destroyClientBuffer(Surface* surface)
119 {
120     EglXPlatformSurface* nativeSurface = (EglXPlatformSurface*)surface->platform;
121     // We have to clean up the gpu texture memory
122     if (nativeSurface && nativeSurface->eglImage)
123     {
124         m_pfEglDestroyImageKHR(m_eglDisplay, nativeSurface->eglImage);
125         glDeleteTextures(1, &nativeSurface->texture);
126         nativeSurface->eglImage = 0;
127         nativeSurface->texture = 0;
128     }
129     // We have to clean up the XServer side pixmap too
130     if (nativeSurface && nativeSurface->pixmap)
131     {
132         XFreePixmap(m_x11display, nativeSurface->pixmap);
133         nativeSurface->pixmap = None;
134     }
135 }