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>
31d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis#include <ui/Fence.h>
320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian#include <ui/FramebufferNativeWindow.h>
335f2165f9455d4893b581b73a67c5431f4344b47eMathias Agopian#include <ui/Rect.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <EGL/egl.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
37076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/hardware.h>
38076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
447189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianclass NativeBuffer
455f2165f9455d4893b581b73a67c5431f4344b47eMathias Agopian    : public ANativeObjectBase<
46697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer,
477189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian        NativeBuffer,
487189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian        LightRefBase<NativeBuffer> >
497189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian{
507189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianpublic:
517189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian    NativeBuffer(int w, int h, int f, int u) : BASE() {
52697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer::width  = w;
53697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer::height = h;
54697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer::format = f;
55697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer::usage  = u;
567189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian    }
577189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopianprivate:
587189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian    friend class LightRefBase<NativeBuffer>;
597189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian    ~NativeBuffer() { }; // this class cannot be overloaded
607189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian};
617189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian
627189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian
63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian/*
64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * This implements the (main) framebuffer management. This class is used
65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * mostly by SurfaceFlinger, but also by command line GL application.
66076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
674b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn * In fact this is an implementation of ANativeWindow on top of
68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * the framebuffer.
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Currently it is pretty simple, it manages only two buffers (the front and
71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * back buffer).
72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianFramebufferNativeWindow::FramebufferNativeWindow()
761e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    hw_module_t const* module;
79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        int stride;
81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        int err;
8271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        int i;
8342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        err = framebuffer_open(module, &fbDev);
84e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
8542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian
8642db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        err = gralloc_open(module, &grDev);
87e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
8942db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        // bail out if we can't initialize the modules
9042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        if (!fbDev || !grDev)
9142db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian            return;
92076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
931e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian        mUpdateOnDemand = (fbDev->setUpdateRect != 0);
941e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // initialize the buffer FIFO
960bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        if(fbDev->numFramebuffers >= MIN_NUM_FRAME_BUFFERS &&
970bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed           fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){
980bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed            mNumBuffers = fbDev->numFramebuffers;
990bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        } else {
1000bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed            mNumBuffers = MIN_NUM_FRAME_BUFFERS;
1010bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        }
1020bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        mNumFreeBuffers = mNumBuffers;
103076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mBufferHead = mNumBuffers-1;
104076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
105c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin        /*
106c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * This does not actually change the framebuffer format. It merely
107c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * fakes this format to surfaceflinger so that when it creates
108c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * framebuffer surfaces it will use this format. It's really a giant
109c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * HACK to allow interworking with buggy gralloc+GPU driver
110c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * implementations. You should *NEVER* need to set this for shipping
111c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         * devices.
112c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin         */
113c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin#ifdef FRAMEBUFFER_FORCE_FORMAT
114c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin        *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
115c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin#endif
116c6cd27cbf3ddec77cca97e5bd2b257f80ea99706Dima Zavin
11771484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        for (i = 0; i < mNumBuffers; i++)
11871484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        {
11971484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                buffers[i] = new NativeBuffer(
12071484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
12171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        }
12271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon
12371484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        for (i = 0; i < mNumBuffers; i++)
12471484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        {
12571484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                err = grDev->alloc(grDev,
12671484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        fbDev->width, fbDev->height, fbDev->format,
12771484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
12871484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon
129e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",
13071484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        i, fbDev->width, fbDev->height, strerror(-err));
13171484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon
13271484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                if (err)
13371484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                {
13471484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        mNumBuffers = i;
13571484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        mNumFreeBuffers = i;
13671484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        mBufferHead = mNumBuffers-1;
13771484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                        break;
13871484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon                }
13971484f2f76457287a1fbf5791f530c2b2459aa0cRodrigo Obregon        }
140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1414b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
1424b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
1434b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
1444b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        const_cast<int&>(ANativeWindow::minSwapInterval) =
145a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen            fbDev->minSwapInterval;
1464b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        const_cast<int&>(ANativeWindow::maxSwapInterval) =
147a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen            fbDev->maxSwapInterval;
148a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen    } else {
149e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("Couldn't get gralloc module");
150a455793a8d068a06ae65e1e04170eb24851c0eb1Marco Nelissen    }
151076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1524b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::setSwapInterval = setSwapInterval;
1534b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::dequeueBuffer = dequeueBuffer;
1544b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::queueBuffer = queueBuffer;
1554b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::query = query;
1564b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::perform = perform;
157d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis
158d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED;
159d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED;
160d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias AgopianFramebufferNativeWindow::~FramebufferNativeWindow()
16442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian{
16542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    if (grDev) {
1660bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        for(int i = 0; i < mNumBuffers; i++) {
1670bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed            if (buffers[i] != NULL) {
1680bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed                grDev->free(grDev, buffers[i]->handle);
1690bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed            }
1700bc64be3f5198f8dda1ced21bbc957a1d76efbb7Naseer Ahmed        }
17142db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        gralloc_close(grDev);
17242db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    }
17342db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian
17442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    if (fbDev) {
17542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        framebuffer_close(fbDev);
17642db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    }
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1791e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopianstatus_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r)
1801e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian{
1811e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    if (!mUpdateOnDemand) {
1821e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian        return INVALID_OPERATION;
1831e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    }
1841e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height());
1851e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian}
1861e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
18774faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopianstatus_t FramebufferNativeWindow::compositionComplete()
18874faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian{
18974faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian    if (fbDev->compositionComplete) {
19074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        return fbDev->compositionComplete(fbDev);
19174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian    }
19274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian    return INVALID_OPERATION;
19374faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian}
19474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian
195076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint FramebufferNativeWindow::setSwapInterval(
1964b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn        ANativeWindow* window, int interval)
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
198076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    framebuffer_device_t* fb = getSelf(window)->fbDev;
199076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return fb->setSwapInterval(fb, interval);
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2021d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gillingvoid FramebufferNativeWindow::dump(String8& result) {
2031d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    if (fbDev->common.version >= 1 && fbDev->dump) {
2041d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        const size_t SIZE = 4096;
2051d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        char buffer[SIZE];
2061d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling
2071d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        fbDev->dump(fbDev, buffer, SIZE);
2081d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling        result.append(buffer);
2091d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    }
2101d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling}
2111d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling
21235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian// only for debugging / logging
21335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopianint FramebufferNativeWindow::getCurrentBufferIndex() const
21435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian{
21535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    Mutex::Autolock _l(mutex);
21635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    const int index = mCurrentBufferIndex;
21735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    return index;
21835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian}
21935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
220d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennisint FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window,
221697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer** buffer)
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
223d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    int fenceFd = -1;
224d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    int result = dequeueBuffer(window, buffer, &fenceFd);
225d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    sp<Fence> fence(new Fence(fenceFd));
226d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    int waitResult = fence->wait(Fence::TIMEOUT_NEVER);
227d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    if (waitResult != OK) {
228d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an "
229d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                "error: %d", waitResult);
230d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        return waitResult;
231d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    }
232d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    return result;
233d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis}
234d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis
235d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennisint FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
236d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        ANativeWindowBuffer** buffer, int* fenceFd)
237d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis{
238076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    FramebufferNativeWindow* self = getSelf(window);
239076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(self->mutex);
240076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    framebuffer_device_t* fb = self->fbDev;
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    int index = self->mBufferHead++;
24335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    if (self->mBufferHead >= self->mNumBuffers)
24435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian        self->mBufferHead = 0;
24535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
246a74cbc06493ed941a8a54f2f1d0074f03fc9aafbJesse Hall    // wait for a free non-front buffer
247a74cbc06493ed941a8a54f2f1d0074f03fc9aafbJesse Hall    while (self->mNumFreeBuffers < 2) {
248076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        self->mCondition.wait(self->mutex);
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
250a74cbc06493ed941a8a54f2f1d0074f03fc9aafbJesse Hall    ALOG_ASSERT(self->buffers[index] != self->front);
251a74cbc06493ed941a8a54f2f1d0074f03fc9aafbJesse Hall
252076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // get this buffer
253076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    self->mNumFreeBuffers--;
25435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    self->mCurrentBufferIndex = index;
255076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
256076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    *buffer = self->buffers[index].get();
257d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    *fenceFd = -1;
258076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennisint FramebufferNativeWindow::lockBuffer_DEPRECATED(ANativeWindow* window,
263697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer* buffer)
264076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
2650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    return NO_ERROR;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
268d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennisint FramebufferNativeWindow::queueBuffer_DEPRECATED(ANativeWindow* window,
269697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer* buffer)
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
271d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    return queueBuffer(window, buffer, -1);
272d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis}
273d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis
274d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennisint FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
275d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        ANativeWindowBuffer* buffer, int fenceFd)
276d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis{
277076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    FramebufferNativeWindow* self = getSelf(window);
278076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(self->mutex);
279076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    framebuffer_device_t* fb = self->fbDev;
280076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
28135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
282d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    sp<Fence> fence(new Fence(fenceFd));
283d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    fence->wait(Fence::TIMEOUT_NEVER);
284d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis
28535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    const int index = self->mCurrentBufferIndex;
286076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int res = fb->post(fb, handle);
287076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    self->front = static_cast<NativeBuffer*>(buffer);
288076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    self->mNumFreeBuffers++;
289076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    self->mCondition.broadcast();
290076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return res;
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29341abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchevint FramebufferNativeWindow::query(const ANativeWindow* window,
294cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        int what, int* value)
295cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{
29641abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchev    const FramebufferNativeWindow* self = getSelf(window);
297cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    Mutex::Autolock _l(self->mutex);
298cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    framebuffer_device_t* fb = self->fbDev;
299cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    switch (what) {
300cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        case NATIVE_WINDOW_WIDTH:
301cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian            *value = fb->width;
302cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian            return NO_ERROR;
303cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        case NATIVE_WINDOW_HEIGHT:
304cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian            *value = fb->height;
305cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian            return NO_ERROR;
3066b1f41004fa48e96bab61f508867314261de660bMathias Agopian        case NATIVE_WINDOW_FORMAT:
3076b1f41004fa48e96bab61f508867314261de660bMathias Agopian            *value = fb->format;
3086b1f41004fa48e96bab61f508867314261de660bMathias Agopian            return NO_ERROR;
309391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis        case NATIVE_WINDOW_CONCRETE_TYPE:
310391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis            *value = NATIVE_WINDOW_FRAMEBUFFER;
311391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis            return NO_ERROR;
31297c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian        case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
31397c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            *value = 0;
31497c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            return NO_ERROR;
31597c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian        case NATIVE_WINDOW_DEFAULT_WIDTH:
31697c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            *value = fb->width;
31797c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            return NO_ERROR;
31897c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian        case NATIVE_WINDOW_DEFAULT_HEIGHT:
31997c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            *value = fb->height;
32097c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            return NO_ERROR;
32197c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian        case NATIVE_WINDOW_TRANSFORM_HINT:
32297c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            *value = 0;
32397c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            return NO_ERROR;
324cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    }
32542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    *value = 0;
326cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return BAD_VALUE;
327cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
328cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
3294b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint FramebufferNativeWindow::perform(ANativeWindow* window,
3305221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian        int operation, ...)
3315221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{
3325221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    switch (operation) {
33355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_CONNECT:
33455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_DISCONNECT:
335bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian        case NATIVE_WINDOW_SET_USAGE:
336bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian        case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
337bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian        case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
338bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian        case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
339bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian        case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
34081a63350527cafce6929309533c58586878f10b5Mathias Agopian        case NATIVE_WINDOW_API_CONNECT:
34181a63350527cafce6929309533c58586878f10b5Mathias Agopian        case NATIVE_WINDOW_API_DISCONNECT:
342bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian            // TODO: we should implement these
3437734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian            return NO_ERROR;
344bb66c9b5a9c16dee93559eb738746a2d0a9b2db3Mathias Agopian
3458f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian        case NATIVE_WINDOW_LOCK:
3468f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian        case NATIVE_WINDOW_UNLOCK_AND_POST:
3477734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian        case NATIVE_WINDOW_SET_CROP:
3487734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian        case NATIVE_WINDOW_SET_BUFFER_COUNT:
3497734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian        case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
3507734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian        case NATIVE_WINDOW_SET_SCALING_MODE:
3517734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian            return INVALID_OPERATION;
3525221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    }
3537734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian    return NAME_NOT_FOUND;
3545221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
3555221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
359076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
36042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopianusing namespace android;
361076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
362076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianEGLNativeWindowType android_createDisplaySurface(void)
363076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
36442db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    FramebufferNativeWindow* w;
36542db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    w = new FramebufferNativeWindow();
36642db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    if (w->getDevice() == NULL) {
36742db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        // get a ref so it can be destroyed when we exit this block
36842db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        sp<FramebufferNativeWindow> ref(w);
36942db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian        return NULL;
37042db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    }
37142db9dcea2e6b9f60f07a3e9e2d6fbc196082284Mathias Agopian    return (EGLNativeWindowType)w;
372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
373