summaryrefslogtreecommitdiffstats
path: root/libs/ui/EGLNativeWindowSurface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/EGLNativeWindowSurface.cpp')
-rw-r--r--libs/ui/EGLNativeWindowSurface.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
new file mode 100644
index 0000000..0b6afc0
--- /dev/null
+++ b/libs/ui/EGLNativeWindowSurface.cpp
@@ -0,0 +1,181 @@
+/*
+**
+** Copyright 2007 The Android Open Source Project
+**
+** Licensed under the Apache License Version 2.0(the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing software
+** distributed under the License is distributed on an "AS IS" BASIS
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "EGLNativeWindowSurface"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+
+#include <GLES/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include <ui/EGLNativeWindowSurface.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
+ : EGLNativeSurface<EGLNativeWindowSurface>(),
+ mSurface(surface), mConnected(false)
+{
+ egl_native_window_t::magic = 0x600913;
+ egl_native_window_t::version = sizeof(egl_native_window_t);
+ egl_native_window_t::ident = 0;
+ egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
+ egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
+ egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
+ egl_native_window_t::nextBuffer = &EGLNativeWindowSurface::hook_nextBuffer;
+ egl_native_window_t::setSwapRectangle = &EGLNativeWindowSurface::hook_setSwapRectangle;
+ egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
+ egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
+
+ DisplayInfo dinfo;
+ SurfaceComposerClient::getDisplayInfo(0, &dinfo);
+ egl_native_window_t::xdpi = dinfo.xdpi;
+ egl_native_window_t::ydpi = dinfo.ydpi;
+ egl_native_window_t::fps = dinfo.fps;
+ egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
+}
+
+EGLNativeWindowSurface::~EGLNativeWindowSurface()
+{
+ disconnect();
+ mSurface.clear();
+ magic = 0;
+}
+
+void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ that->incStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ that->decStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ that->connect();
+}
+
+void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ that->disconnect();
+}
+
+uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ return that->swapBuffers();
+}
+
+uint32_t EGLNativeWindowSurface::hook_nextBuffer(NativeWindowType window)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ return that->nextBuffer();
+}
+
+void EGLNativeWindowSurface::hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h)
+{
+ EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+ that->setSwapRectangle(l, t, w, h);
+}
+
+void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
+{
+ mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
+}
+
+uint32_t EGLNativeWindowSurface::swapBuffers()
+{
+ const int w = egl_native_window_t::width;
+ const int h = egl_native_window_t::height;
+ const sp<Surface>& surface(mSurface);
+ Surface::SurfaceInfo info;
+ surface->unlockAndPost();
+ surface->lock(&info);
+ // update the address of the buffer to draw to next
+ egl_native_window_t::base = intptr_t(info.base);
+ egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+
+ // update size if it changed
+ if (w != int(info.w) || h != int(info.h)) {
+ egl_native_window_t::width = info.w;
+ egl_native_window_t::height = info.h;
+ egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+ egl_native_window_t::format = info.format;
+ return EGL_NATIVES_FLAG_SIZE_CHANGED;
+ }
+ return 0;
+}
+
+uint32_t EGLNativeWindowSurface::nextBuffer()
+{
+ const sp<Surface>& surface(mSurface);
+ Surface::SurfaceInfo info;
+ surface->nextBuffer(&info);
+ // update the address of the buffer to draw to next
+ egl_native_window_t::base = intptr_t(info.base);
+ egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+ return 0;
+}
+
+void EGLNativeWindowSurface::connect()
+{
+ if (!mConnected) {
+ Surface::SurfaceInfo info;
+ mSurface->lock(&info);
+ mSurface->setSwapRectangle(Rect(info.w, info.h));
+ mConnected = true;
+
+ egl_native_window_t::width = info.w;
+ egl_native_window_t::height = info.h;
+ egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+ egl_native_window_t::format = info.format;
+ egl_native_window_t::base = intptr_t(info.base);
+ egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+ egl_native_window_t::memory_type = mSurface->getMemoryType();
+ egl_native_window_t::fd = 0;
+ }
+}
+
+void EGLNativeWindowSurface::disconnect()
+{
+ if (mConnected) {
+ mSurface->unlock();
+ mConnected = false;
+ }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------