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