blob: d55fb7090ff618521e0e2a84096cc8eb49b10160 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2**
3** Copyright 2007 The Android Open Source Project
4**
5** Licensed under the Apache License Version 2.0(the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing software
12** distributed under the License is distributed on an "AS IS" BASIS
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "EGLNativeWindowSurface"
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23
24#include <cutils/log.h>
25#include <cutils/atomic.h>
26
27#include <ui/SurfaceComposerClient.h>
28#include <ui/DisplayInfo.h>
29#include <ui/Rect.h>
30
31#include <GLES/egl.h>
32
33#include <pixelflinger/format.h>
34
35#include <ui/EGLNativeWindowSurface.h>
36
37// ----------------------------------------------------------------------------
38namespace android {
39// ----------------------------------------------------------------------------
40
41EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
42 : EGLNativeSurface<EGLNativeWindowSurface>(),
43 mSurface(surface), mConnected(false)
44{
45 egl_native_window_t::magic = 0x600913;
46 egl_native_window_t::version = sizeof(egl_native_window_t);
47 egl_native_window_t::ident = 0;
48 egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
49 egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
50 egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
51 egl_native_window_t::nextBuffer = &EGLNativeWindowSurface::hook_nextBuffer;
52 egl_native_window_t::setSwapRectangle = &EGLNativeWindowSurface::hook_setSwapRectangle;
53 egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
54 egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
55
56 DisplayInfo dinfo;
57 SurfaceComposerClient::getDisplayInfo(0, &dinfo);
58 egl_native_window_t::xdpi = dinfo.xdpi;
59 egl_native_window_t::ydpi = dinfo.ydpi;
60 egl_native_window_t::fps = dinfo.fps;
61 egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
62}
63
64EGLNativeWindowSurface::~EGLNativeWindowSurface()
65{
66 disconnect();
67 mSurface.clear();
68 magic = 0;
69}
70
71void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
72{
73 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
74 that->incStrong(that);
75}
76
77void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
78{
79 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
80 that->decStrong(that);
81}
82
83void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
84{
85 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
86 that->connect();
87}
88
89void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
90{
91 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
92 that->disconnect();
93}
94
95uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
96{
97 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
98 return that->swapBuffers();
99}
100
101uint32_t EGLNativeWindowSurface::hook_nextBuffer(NativeWindowType window)
102{
103 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
104 return that->nextBuffer();
105}
106
107void EGLNativeWindowSurface::hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h)
108{
109 EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
110 that->setSwapRectangle(l, t, w, h);
111}
112
113void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
114{
115 mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
116}
117
118uint32_t EGLNativeWindowSurface::swapBuffers()
119{
120 const int w = egl_native_window_t::width;
121 const int h = egl_native_window_t::height;
122 const sp<Surface>& surface(mSurface);
123 Surface::SurfaceInfo info;
124 surface->unlockAndPost();
125 surface->lock(&info);
126 // update the address of the buffer to draw to next
127 egl_native_window_t::base = intptr_t(info.base);
128 egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
129
130 // update size if it changed
131 if (w != int(info.w) || h != int(info.h)) {
132 egl_native_window_t::width = info.w;
133 egl_native_window_t::height = info.h;
134 egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
135 egl_native_window_t::format = info.format;
136 return EGL_NATIVES_FLAG_SIZE_CHANGED;
137 }
138 return 0;
139}
140
141uint32_t EGLNativeWindowSurface::nextBuffer()
142{
143 const sp<Surface>& surface(mSurface);
144 Surface::SurfaceInfo info;
145 surface->nextBuffer(&info);
146 // update the address of the buffer to draw to next
147 egl_native_window_t::base = intptr_t(info.base);
148 egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
149 return 0;
150}
151
152void EGLNativeWindowSurface::connect()
153{
154 if (!mConnected) {
155 Surface::SurfaceInfo info;
156 mSurface->lock(&info);
157 mSurface->setSwapRectangle(Rect(info.w, info.h));
158 mConnected = true;
159
160 egl_native_window_t::width = info.w;
161 egl_native_window_t::height = info.h;
162 egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
163 egl_native_window_t::format = info.format;
164 egl_native_window_t::base = intptr_t(info.base);
165 egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800166 // FIXME: egl_native_window_t::memory_type used to be set from
167 // mSurface, but we wanted to break this dependency. We set it to
168 // GPU because the software rendered doesn't care, but the h/w
169 // accelerator needs it. Eventually, this value should go away
170 // completely, since memory will be managed by OpenGL.
171 egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_GPU;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700172 egl_native_window_t::fd = 0;
173 }
174}
175
176void EGLNativeWindowSurface::disconnect()
177{
178 if (mConnected) {
179 mSurface->unlock();
180 mConnected = false;
181 }
182}
183
184// ----------------------------------------------------------------------------
185}; // namespace android
186// ----------------------------------------------------------------------------