diff options
Diffstat (limited to 'libs/ui/EGLNativeWindowSurface.cpp')
-rw-r--r-- | libs/ui/EGLNativeWindowSurface.cpp | 181 |
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 +// ---------------------------------------------------------------------------- |