Initial support for Wayland 1.3.
[profile/ivi/layer-management.git] / LayerManagerPlugins / Renderers / Graphic / src / TextureBinders / WaylandGLESTexture.cpp
1 /***************************************************************************
2 *
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *        http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ****************************************************************************/
20
21 #include "TextureBinders/WaylandGLESTexture.h"
22 #include <EGL/egl.h>
23 #include <EGL/eglext.h>
24 #include <GLES2/gl2ext.h>
25 #include "PlatformSurfaces/EglWaylandPlatformSurface.h"
26 #include "Log.h"
27 #include "wayland-server.h"
28 #include "config.h"
29
30 WaylandGLESTexture::WaylandGLESTexture(EGLDisplay eglDisplay, struct wl_display* wlDisplay)
31 : m_eglDisplay(eglDisplay)
32 , m_wlDisplay(wlDisplay)
33 {
34     // pseudo require EGL to have been initialised
35     // we dont really need the EGL handle as such
36
37     m_pfGLEglImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
38     m_pfEglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
39     m_pfEglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
40
41     if (!m_pfEglCreateImageKHR || !m_pfEglDestroyImageKHR || !m_pfGLEglImageTargetTexture2DOES)
42     {
43         LOG_ERROR("WaylandGLESTexture", "Query EGL Extensions failed");
44     }
45 }
46
47 WaylandGLESTexture::~WaylandGLESTexture()
48 {
49 }
50
51 bool WaylandGLESTexture::bindSurfaceTexture(Surface* surface)
52 {
53     LOG_DEBUG("WaylandGLESTexture", "bindSurfaceTexture IN");
54     EglWaylandPlatformSurface* nativeSurface = (EglWaylandPlatformSurface*)surface->platform;
55     if (nativeSurface && nativeSurface->isReadyForRendering())
56     {
57         struct wl_buffer* buffer = (struct wl_buffer*)surface->getNativeContent();
58         /**
59          * @todo Port to Wayland 1.3.
60          */
61         if (0 // wl_buffer_is_shm(buffer)
62             )
63         {
64             /* Wayland SHM buffer */
65             /**
66              * @todo Port to Wayland 1.3.
67              */
68             unsigned int* pBuf = (unsigned int*)wl_shm_buffer_get_data(NULL // buffer
69                 );
70             if ((NULL != buffer) && (NULL != pBuf))
71             {
72                 LOG_DEBUG("WaylandGLESTexture", "SHM buffer address:" << pBuf);
73                 unsigned int* pTmp = (unsigned int*)pBuf;
74                 unsigned int col = 0;
75                 int cnt = 0;
76                 unsigned int* pCnvImg = (unsigned int*)malloc(sizeof(unsigned int)
77                                                 * surface->OriginalSourceWidth * surface->OriginalSourceHeight);
78                 unsigned int* pCnvImgTmp = pCnvImg;
79                 for (cnt = 0; cnt < surface->OriginalSourceWidth * surface->OriginalSourceHeight; cnt++, pTmp++, pCnvImgTmp++)
80                 {
81                     col = (unsigned int)*pTmp;
82                     // TODO:endian
83                     *pCnvImgTmp = (col&0xFF00FF00) | ((col&0x00FF0000)>>16) | ((col&0x000000FF)<<16);
84                 }
85
86                 glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
87                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
88                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
89                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
91                 glTexImage2D(GL_TEXTURE_2D,
92                              0,
93                              GL_RGBA,
94                              surface->OriginalSourceWidth,
95                              surface->OriginalSourceHeight,
96                              0,
97                              GL_RGBA,
98                              GL_UNSIGNED_BYTE,
99                              pCnvImg);
100                 free(pCnvImg);
101             }
102             return true;
103         }
104         else
105         {
106             /* Wayland Not SHM buffer */
107             if (nativeSurface->eglImage)
108             {
109                 LOG_DEBUG("WaylandGLESTexture", "nativeSurface->eglImage:" << nativeSurface->eglImage);
110                 glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
111                 return true;
112             }
113         }
114
115         LOG_DEBUG("WaylandGLESTexture", "bindSurfaceTexture OUT");
116         return true;
117     }
118     LOG_DEBUG("WaylandGLESTexture", "bindSurfaceTexture ERROR OUT");
119     return false;
120 }
121
122 bool WaylandGLESTexture::unbindSurfaceTexture(Surface* surface)
123 {
124     LOG_DEBUG("WaylandGLESTexture", "unbindSurfaceTexture:surface" << surface);
125     return true;
126 }
127
128 void WaylandGLESTexture::createClientBuffer(Surface* surface)
129 {
130     LOG_DEBUG("WaylandGLESTexture", "creating client buffer with native display: " << m_wlDisplay << " for native handle: " << surface->getNativeContent());
131     EglWaylandPlatformSurface* nativeSurface = (EglWaylandPlatformSurface*)surface->platform;
132
133     if (NULL != nativeSurface)
134     {
135         struct wl_buffer* buffer = (struct wl_buffer*)surface->getNativeContent();
136         /**
137          * @todo Port to Wayland 1.3.
138          */
139         if (0 // wl_buffer_is_shm(buffer)
140             )
141         {
142             if (nativeSurface->texture)
143             {
144                 glDeleteTextures(1, &nativeSurface->texture);
145                 nativeSurface->texture = 0;
146             }
147             glGenTextures(1, &nativeSurface->texture);
148         }
149         else
150         {
151             EGLImageKHR eglImage = 0;
152             LOG_DEBUG("WaylandGLESTexture", "creating EGL Image from client buffer");
153             if (nativeSurface->eglImage)
154             {
155                 m_pfEglDestroyImageKHR(m_eglDisplay, nativeSurface->eglImage);
156                 glDeleteTextures(1, &nativeSurface->texture);
157                 nativeSurface->eglImage = 0;
158                 nativeSurface->texture = 0;
159             }
160             eglImage = m_pfEglCreateImageKHR(m_eglDisplay,
161                                             EGL_NO_CONTEXT,
162                                             EGL_WAYLAND_BUFFER_WL,
163                                             (EGLClientBuffer)buffer,
164                                             NULL);
165             if (!eglImage)
166             {
167                 LOG_DEBUG("WaylandGLESTexture", "could not allocate EGL Image for window");
168             }
169             else
170             {
171                 nativeSurface->eglImage = eglImage;
172                 glGenTextures(1, &nativeSurface->texture);
173                 glBindTexture(GL_TEXTURE_2D, nativeSurface->texture);
174                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
175                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
176                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
177                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
178                 m_pfGLEglImageTargetTexture2DOES(GL_TEXTURE_2D, nativeSurface->eglImage);
179             }
180         }
181     }
182 }
183
184 PlatformSurface* WaylandGLESTexture::createPlatformSurface(Surface* surface)
185 {
186     return new EglWaylandPlatformSurface(surface);
187 }
188
189 void WaylandGLESTexture::destroyClientBuffer(Surface* surface)
190 {
191     EglWaylandPlatformSurface* nativeSurface = (EglWaylandPlatformSurface*)surface->platform;
192
193     struct wl_buffer* buffer = (struct wl_buffer*)surface->getNativeContent();
194     /**
195      * @todo Port to Wayland 1.3.
196      */
197     if (0 // wl_buffer_is_shm(buffer)
198         )
199     {
200         if (nativeSurface && nativeSurface->texture)
201         {
202             glDeleteTextures(1, &nativeSurface->texture);
203             nativeSurface->texture = 0;
204         }
205     }
206     else
207     {
208         if (nativeSurface && nativeSurface->eglImage)
209         {
210             m_pfEglDestroyImageKHR(m_eglDisplay, nativeSurface->eglImage);
211             glDeleteTextures(1, &nativeSurface->texture);
212             nativeSurface->eglImage = 0;
213             nativeSurface->texture = 0;
214         }
215     }
216 }