1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2007 The Android Open Source Project 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Licensed under the Apache License Version 2.0(the "License"); 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** you may not use this file except in compliance with the License. 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** You may obtain a copy of the License at 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Unless required by applicable law or agreed to in writing software 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** See the License for the specific language governing permissions and 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License. 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/ 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian#define LOG_TAG "FramebufferNativeWindow" 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <string.h> 23076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <errno.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/atomic.h> 27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/threads.h> 2842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian#include <utils/RefBase.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305f2165f9455d4893b581b73a67c5431f4344b47eMathias Agopian#include <ui/ANativeObjectBase.h> 310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian#include <ui/FramebufferNativeWindow.h> 325f2165f9455d4893b581b73a67c5431f4344b47eMathias Agopian#include <ui/Rect.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <EGL/egl.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/hardware.h> 37076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 437189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianclass NativeBuffer 445f2165f9455d4893b581b73a67c5431f4344b47eMathias Agopian : public ANativeObjectBase< 45697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer, 467189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian NativeBuffer, 477189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian LightRefBase<NativeBuffer> > 487189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian{ 497189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianpublic: 507189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian NativeBuffer(int w, int h, int f, int u) : BASE() { 51697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer::width = w; 52697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer::height = h; 53697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer::format = f; 54697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer::usage = u; 557189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian } 567189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianprivate: 577189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian friend class LightRefBase<NativeBuffer>; 587189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian ~NativeBuffer() { }; // this class cannot be overloaded 597189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian}; 607189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian 617189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian 62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian/* 63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * This implements the (main) framebuffer management. This class is used 64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * mostly by SurfaceFlinger, but also by command line GL application. 65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * 664b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn * In fact this is an implementation of ANativeWindow on top of 67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * the framebuffer. 68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * 69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Currently it is pretty simple, it manages only two buffers (the front and 70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * back buffer). 71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * 72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */ 73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianFramebufferNativeWindow::FramebufferNativeWindow() 751e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false) 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian hw_module_t const* module; 78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { 79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int stride; 80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int err; 8171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon int i; 8242db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian err = framebuffer_open(module, &fbDev); 83e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); 8442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian 8542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian err = gralloc_open(module, &grDev); 86e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err)); 87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 8842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian // bail out if we can't initialize the modules 8942db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (!fbDev || !grDev) 9042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian return; 91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 921e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian mUpdateOnDemand = (fbDev->setUpdateRect != 0); 931e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian 94076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // initialize the buffer FIFO 9571484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon mNumBuffers = NUM_FRAME_BUFFERS; 9671484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon mNumFreeBuffers = NUM_FRAME_BUFFERS; 97076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mBufferHead = mNumBuffers-1; 98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 99c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin /* 100c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * This does not actually change the framebuffer format. It merely 101c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * fakes this format to surfaceflinger so that when it creates 102c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * framebuffer surfaces it will use this format. It's really a giant 103c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * HACK to allow interworking with buggy gralloc+GPU driver 104c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * implementations. You should *NEVER* need to set this for shipping 105c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin * devices. 106c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin */ 107c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin#ifdef FRAMEBUFFER_FORCE_FORMAT 108c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT; 109c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin#endif 110c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin 11171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon for (i = 0; i < mNumBuffers; i++) 11271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon { 11371484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon buffers[i] = new NativeBuffer( 11471484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); 11571484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon } 11671484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon 11771484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon for (i = 0; i < mNumBuffers; i++) 11871484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon { 11971484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon err = grDev->alloc(grDev, 12071484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon fbDev->width, fbDev->height, fbDev->format, 12171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride); 12271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon 123e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s", 12471484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon i, fbDev->width, fbDev->height, strerror(-err)); 12571484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon 12671484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon if (err) 12771484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon { 12871484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon mNumBuffers = i; 12971484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon mNumFreeBuffers = i; 13071484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon mBufferHead = mNumBuffers-1; 13171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon break; 13271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon } 13371484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon } 134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 1354b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; 1364b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; 1374b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; 1384b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn const_cast<int&>(ANativeWindow::minSwapInterval) = 139a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen fbDev->minSwapInterval; 1404b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn const_cast<int&>(ANativeWindow::maxSwapInterval) = 141a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen fbDev->maxSwapInterval; 142a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen } else { 143e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Couldn't get gralloc module"); 144a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen } 145076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 1464b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::setSwapInterval = setSwapInterval; 1474b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::dequeueBuffer = dequeueBuffer; 1484b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::lockBuffer = lockBuffer; 1494b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::queueBuffer = queueBuffer; 1504b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::query = query; 1514b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::perform = perform; 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias AgopianFramebufferNativeWindow::~FramebufferNativeWindow() 15542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian{ 15642db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (grDev) { 15742db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (buffers[0] != NULL) 15842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian grDev->free(grDev, buffers[0]->handle); 15942db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (buffers[1] != NULL) 16042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian grDev->free(grDev, buffers[1]->handle); 16142db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian gralloc_close(grDev); 16242db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian } 16342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian 16442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (fbDev) { 16542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian framebuffer_close(fbDev); 16642db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian } 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1691e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopianstatus_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r) 1701e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian{ 1711e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian if (!mUpdateOnDemand) { 1721e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian return INVALID_OPERATION; 1731e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian } 1741e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height()); 1751e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian} 1761e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian 17774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopianstatus_t FramebufferNativeWindow::compositionComplete() 17874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian{ 17974faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian if (fbDev->compositionComplete) { 18074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian return fbDev->compositionComplete(fbDev); 18174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian } 18274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian return INVALID_OPERATION; 18374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian} 18474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian 185076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint FramebufferNativeWindow::setSwapInterval( 1864b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow* window, int interval) 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian framebuffer_device_t* fb = getSelf(window)->fbDev; 189076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return fb->setSwapInterval(fb, interval); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1921d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gillingvoid FramebufferNativeWindow::dump(String8& result) { 1931d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling if (fbDev->common.version >= 1 && fbDev->dump) { 1941d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling const size_t SIZE = 4096; 1951d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling char buffer[SIZE]; 1961d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling 1971d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling fbDev->dump(fbDev, buffer, SIZE); 1981d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling result.append(buffer); 1991d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling } 2001d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling} 2011d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling 20235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian// only for debugging / logging 20335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopianint FramebufferNativeWindow::getCurrentBufferIndex() const 20435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian{ 20535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian Mutex::Autolock _l(mutex); 20635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = mCurrentBufferIndex; 20735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian return index; 20835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian} 20935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 2104b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 211697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer** buffer) 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 213076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian FramebufferNativeWindow* self = getSelf(window); 214076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(self->mutex); 215076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian framebuffer_device_t* fb = self->fbDev; 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian int index = self->mBufferHead++; 21835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian if (self->mBufferHead >= self->mNumBuffers) 21935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian self->mBufferHead = 0; 22035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 221076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // wait for a free buffer 222076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian while (!self->mNumFreeBuffers) { 223076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->mCondition.wait(self->mutex); 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 225076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // get this buffer 226076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->mNumFreeBuffers--; 22735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian self->mCurrentBufferIndex = index; 228076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 229076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *buffer = self->buffers[index].get(); 230076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2344b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 235697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* buffer) 236076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 237076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian FramebufferNativeWindow* self = getSelf(window); 238076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(self->mutex); 239076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 24035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = self->mCurrentBufferIndex; 24135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 242076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // wait that the buffer we're locking is not front anymore 243076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian while (self->front == buffer) { 244076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->mCondition.wait(self->mutex); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 246076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 2470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return NO_ERROR; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2504b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint FramebufferNativeWindow::queueBuffer(ANativeWindow* window, 251697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* buffer) 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 253076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian FramebufferNativeWindow* self = getSelf(window); 254076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(self->mutex); 255076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian framebuffer_device_t* fb = self->fbDev; 256076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle; 25735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian 25835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian const int index = self->mCurrentBufferIndex; 259076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int res = fb->post(fb, handle); 260076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->front = static_cast<NativeBuffer*>(buffer); 261076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->mNumFreeBuffers++; 262076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->mCondition.broadcast(); 263076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return res; 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26641abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchevint FramebufferNativeWindow::query(const ANativeWindow* window, 267cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian int what, int* value) 268cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{ 26941abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchev const FramebufferNativeWindow* self = getSelf(window); 270cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian Mutex::Autolock _l(self->mutex); 271cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian framebuffer_device_t* fb = self->fbDev; 272cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian switch (what) { 273cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian case NATIVE_WINDOW_WIDTH: 274cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian *value = fb->width; 275cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return NO_ERROR; 276cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian case NATIVE_WINDOW_HEIGHT: 277cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian *value = fb->height; 278cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return NO_ERROR; 2796b1f41004fa48e96bab61f508867314261de660bMathias Agopian case NATIVE_WINDOW_FORMAT: 2806b1f41004fa48e96bab61f508867314261de660bMathias Agopian *value = fb->format; 2816b1f41004fa48e96bab61f508867314261de660bMathias Agopian return NO_ERROR; 282391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis case NATIVE_WINDOW_CONCRETE_TYPE: 283391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis *value = NATIVE_WINDOW_FRAMEBUFFER; 284391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis return NO_ERROR; 28597c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: 28697c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian *value = 0; 28797c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian return NO_ERROR; 28897c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian case NATIVE_WINDOW_DEFAULT_WIDTH: 28997c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian *value = fb->width; 29097c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian return NO_ERROR; 29197c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian case NATIVE_WINDOW_DEFAULT_HEIGHT: 29297c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian *value = fb->height; 29397c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian return NO_ERROR; 29497c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian case NATIVE_WINDOW_TRANSFORM_HINT: 29597c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian *value = 0; 29697c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian return NO_ERROR; 297cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian } 29842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian *value = 0; 299cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return BAD_VALUE; 300cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 301cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 3024b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint FramebufferNativeWindow::perform(ANativeWindow* window, 3035221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int operation, ...) 3045221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{ 3055221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian switch (operation) { 30655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_CONNECT: 30755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_DISCONNECT: 308bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian case NATIVE_WINDOW_SET_USAGE: 309bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: 310bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: 311bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_FORMAT: 312bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: 31381a63350527cafce6929309533c58586878f10b5Mathias Agopian case NATIVE_WINDOW_API_CONNECT: 31481a63350527cafce6929309533c58586878f10b5Mathias Agopian case NATIVE_WINDOW_API_DISCONNECT: 315bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian // TODO: we should implement these 3167734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return NO_ERROR; 317bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian 3188f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian case NATIVE_WINDOW_LOCK: 3198f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian case NATIVE_WINDOW_UNLOCK_AND_POST: 3207734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SET_CROP: 3217734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SET_BUFFER_COUNT: 3227734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: 3237734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SET_SCALING_MODE: 3247734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return INVALID_OPERATION; 3255221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian } 3267734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return NAME_NOT_FOUND; 3275221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 3285221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 332076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 33342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopianusing namespace android; 334076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 335076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLNativeWindowType android_createDisplaySurface(void) 336076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 33742db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian FramebufferNativeWindow* w; 33842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian w = new FramebufferNativeWindow(); 33942db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian if (w->getDevice() == NULL) { 34042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian // get a ref so it can be destroyed when we exit this block 34142db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian sp<FramebufferNativeWindow> ref(w); 34242db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian return NULL; 34342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian } 34442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian return (EGLNativeWindowType)w; 345076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 346