Surface.cpp revision 391bbe2246a7547dbf3460c231b3c5ba691d4eb1
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "Surface"
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
26cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <utils/CallStack.h>
279cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <utils/Log.h>
289cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h>
333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferMapper.h>
3535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
389cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h>
399cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurface.h>
409cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurfaceComposer.h>
419cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/SurfaceComposerClient.h>
42076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
439cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
449cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/LayerState.h>
45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------
49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5014998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt(
513330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const sp<GraphicBuffer>& dst,
523330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const sp<GraphicBuffer>& src,
530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        const Region& reg)
54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
55245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    // src and dst with, height and format must be identical. no verification
56245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    // is done here.
5714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    status_t err;
5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t const * src_bits = NULL;
5914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
6014998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
6214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t* dst_bits = NULL;
6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator head(reg.begin());
6714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator tail(reg.end());
6814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (head != tail && src_bits && dst_bits) {
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t bpp = bytesPerPixel(src->format);
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t dbpr = dst->stride * bpp;
71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t sbpr = src->stride * bpp;
720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        while (head != tail) {
7414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian            const Rect& r(*head++);
750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ssize_t h = r.height();
760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (h <= 0) continue;
770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            size_t size = r.width() * bpp;
780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (dbpr==sbpr && size==sbpr) {
810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                size *= h;
820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                h = 1;
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            do {
850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                memcpy(d, s, size);
860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                d += dbpr;
870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                s += sbpr;
880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            } while (--h > 0);
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
910926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
9214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (src_bits)
9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        src->unlock();
9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (dst_bits)
9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        dst->unlock();
9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    return err;
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
10162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian//  SurfaceControl
10362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
10501b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl(
10601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceComposerClient>& client,
10762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const sp<ISurface>& surface,
1087e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const ISurfaceComposerClient::surface_data_t& data,
10918d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
11062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    : mClient(client), mSurface(surface),
11162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian      mToken(data.token), mIdentity(data.identity),
1121c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mWidth(data.width), mHeight(data.height), mFormat(data.format),
1131c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mFlags(flags)
11462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
11618d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian
11762185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl()
11862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
12062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
12162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy()
12362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
12418d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian    if (isValid()) {
12562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        mClient->destroySurface(mToken);
12662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
12762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // clear all references and trigger an IPC now, to make sure things
12962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // happen without delay, since these resources are quite heavy.
13062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mClient.clear();
13162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurface.clear();
13262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    IPCThreadState::self()->flushCommands();
13362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
13462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
13562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear()
13662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
13762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // here, the window manager tells us explicitly that we should destroy
13862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // the surface's resource. Soon after this call, it will also release
13962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // its last reference (which will call the dtor); however, it is possible
14062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // that a client living in the same process still holds references which
14162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // would delay the call to the dtor -- that is why we need this explicit
14262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // "clear()" call.
14362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
14462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
14562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
14601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface(
14701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
14801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
14901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (lhs == 0 || rhs == 0)
15001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        return false;
15101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
15201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
15301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
15462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) {
155963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
15662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
157631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setLayer(mToken, layer);
15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) {
161963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
16262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
163631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setPosition(mToken, x, y);
16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
167963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
16862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
169631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setSize(mToken, w, h);
17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() {
173963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
175631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
17662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->hide(mToken);
17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) {
179963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
18062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
181631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->show(mToken, layer);
18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() {
185963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
18662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
187631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->freeze(mToken);
18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
19062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() {
191963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
193631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->unfreeze(mToken);
19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
197963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
199631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFlags(mToken, flags, mask);
20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
203963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
20462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
205631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setTransparentRegionHint(mToken, transparent);
20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) {
209963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
211631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setAlpha(mToken, alpha);
21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
215963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
21662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
217631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) {
221963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
22262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
223631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFreezeTint(mToken, tint);
22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
227963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t SurfaceControl::validate() const
22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mToken<0 || mClient==0) {
23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, mClient.get());
23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return NO_ERROR;
23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
23701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel(
23801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& control, Parcel* parcel)
23901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
240579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    sp<ISurface> sur;
24101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t identity = 0;
242cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t width = 0;
243cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t height = 0;
244579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t format = 0;
245579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t flags = 0;
24601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (SurfaceControl::isValid(control)) {
24701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        sur      = control->mSurface;
248579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        identity = control->mIdentity;
249cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        width    = control->mWidth;
250cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        height   = control->mHeight;
25101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        format   = control->mFormat;
25201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        flags    = control->mFlags;
25301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
254b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
25501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(identity);
256cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(width);
257cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(height);
25801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(format);
25901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(flags);
26001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return NO_ERROR;
26101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
26201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
26301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const
26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    Mutex::Autolock _l(mLock);
26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (mSurfaceData == 0) {
26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return mSurfaceData;
27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
27101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
272076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian//  Surface
274076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianclass SurfaceClient : public Singleton<SurfaceClient>
277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // all these attributes are constants
279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposer> mComposerService;
280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> mClient;
281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t mStatus;
282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedClient* mControl;
283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<IMemoryHeap> mControlMemory;
284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SurfaceClient()
286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        : Singleton<SurfaceClient>(), mStatus(NO_INIT)
287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    {
288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
289b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mComposerService = sf;
290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mClient = sf->createClientConnection();
291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (mClient != NULL) {
292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mControlMemory = mClient->getControlBlock();
293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (mControlMemory != NULL) {
294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mControl = static_cast<SharedClient *>(
295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                        mControlMemory->getBase());
296b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                if (mControl) {
297b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                    mStatus = NO_ERROR;
298b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                }
299b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    friend class Singleton<SurfaceClient>;
303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianpublic:
304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t initCheck() const {
305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mStatus;
306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedClient* getSharedClient() const {
308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mControl;
309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        // TODO: we could cache a few tokens here to avoid an IPC
312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mClient->getTokenForSurface(sur);
313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    void signalServer() const {
315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mComposerService->signal();
316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian};
318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
32301b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface)
324b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mBufferMapper(GraphicBufferMapper::get()),
325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mClient(SurfaceClient::getInstance()),
326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSharedBufferClient(NULL),
327631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian      mInitCheck(NO_INIT),
328b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSurface(surface->mSurface),
329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mIdentity(surface->mIdentity),
330b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mFormat(surface->mFormat), mFlags(surface->mFlags),
331ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian      mWidth(surface->mWidth), mHeight(surface->mHeight)
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
33301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
33401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
33562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
336a0c30e924193da57723fd53b710ce6be24fb26f5Mathias AgopianSurface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
337b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mBufferMapper(GraphicBufferMapper::get()),
338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mClient(SurfaceClient::getInstance()),
339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSharedBufferClient(NULL),
340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mInitCheck(NO_INIT)
34101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
342a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    mSurface    = interface_cast<ISurface>(ref);
34301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mIdentity   = parcel.readInt32();
344cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mWidth      = parcel.readInt32();
345cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mHeight     = parcel.readInt32();
34601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFormat     = parcel.readInt32();
34701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFlags      = parcel.readInt32();
34801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
34901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
35001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
351579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopianstatus_t Surface::writeToParcel(
352579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        const sp<Surface>& surface, Parcel* parcel)
353579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{
354579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    sp<ISurface> sur;
355579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t identity = 0;
356579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t width = 0;
357579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t height = 0;
358579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t format = 0;
359579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    uint32_t flags = 0;
360579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if (Surface::isValid(surface)) {
361579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        sur      = surface->mSurface;
362579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        identity = surface->mIdentity;
363579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        width    = surface->mWidth;
364579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        height   = surface->mHeight;
365579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        format   = surface->mFormat;
366579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        flags    = surface->mFlags;
36789c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis    } else if (surface != 0 && surface->mSurface != 0) {
36889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis        LOGW("Parceling invalid surface with non-NULL ISurface as NULL: "
36989c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis             "mSurface = %p, mIdentity = %d, mWidth = %d, mHeight = %d, "
37089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis             "mFormat = %d, mFlags = 0x%08x, mInitCheck = %d",
37189c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis             surface->mSurface.get(), surface->mIdentity, surface->mWidth,
37289c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis             surface->mHeight, surface->mFormat, surface->mFlags,
37389c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis             surface->mInitCheck);
374579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    }
375579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
376579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeInt32(identity);
377579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeInt32(width);
378579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeInt32(height);
379579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeInt32(format);
380579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    parcel->writeInt32(flags);
381579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    return NO_ERROR;
382579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
383579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
384579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
385aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis
386aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie GennisMutex Surface::sCachedSurfacesLock;
387455d18d4c26a823bff62ca14771986cca52d3462Mathias AgopianDefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
388aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis
389aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennissp<Surface> Surface::readFromParcel(const Parcel& data) {
390aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    Mutex::Autolock _l(sCachedSurfacesLock);
391a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    sp<IBinder> binder(data.readStrongBinder());
392aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
393aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    if (surface == 0) {
394aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis       surface = new Surface(data, binder);
395aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis       sCachedSurfaces.add(binder, surface);
396aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    }
397aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    if (surface->mSurface == 0) {
398aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis      surface = 0;
399aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    }
400455d18d4c26a823bff62ca14771986cca52d3462Mathias Agopian    cleanCachedSurfacesLocked();
401aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    return surface;
402aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis}
403aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis
404aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis// Remove the stale entries from the surface cache.  This should only be called
405aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis// with sCachedSurfacesLock held.
406455d18d4c26a823bff62ca14771986cca52d3462Mathias Agopianvoid Surface::cleanCachedSurfacesLocked() {
407aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis    for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
408aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis        wp<Surface> s(sCachedSurfaces.valueAt(i));
409aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis        if (s == 0 || s.promote() == 0) {
410aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis            sCachedSurfaces.removeItemsAt(i);
411aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis        }
412a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    }
413a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian}
414a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian
41501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init()
41601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
4174b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::setSwapInterval  = setSwapInterval;
4184b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::dequeueBuffer    = dequeueBuffer;
41919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    ANativeWindow::cancelBuffer     = cancelBuffer;
4204b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::lockBuffer       = lockBuffer;
4214b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::queueBuffer      = queueBuffer;
4224b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::query            = query;
4234b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    ANativeWindow::perform          = perform;
424631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
425076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    DisplayInfo dinfo;
426076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
4274b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
4284b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: set real values here
4304b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
4314b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
4324b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn    const_cast<uint32_t&>(ANativeWindow::flags) = 0;
433631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
434b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mNextBufferTransform = 0;
43555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    mConnected = 0;
436631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    mSwapRectangle.makeInvalid();
437b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mNextBufferCrop = Rect(0,0);
438a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // two buffers by default
439a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.setCapacity(2);
440a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.insertAt(0, 2);
441631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
442b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
443579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        int32_t token = mClient.getTokenForSurface(mSurface);
444579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        if (token >= 0) {
445b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mSharedBufferClient = new SharedBufferClient(
446579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                    mClient.getSharedClient(), token, 2, mIdentity);
447579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian            mInitCheck = mClient.getSharedClient()->validate(token);
44889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis        } else {
44989c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis            LOGW("Not initializing the shared buffer client because token = %d",
45089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis                    token);
451b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
452631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    }
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface()
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
45740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // clear all references and trigger an IPC now, to make sure things
45840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // happen without delay, since these resources are quite heavy.
459a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.clear();
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurface.clear();
461cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    delete mSharedBufferClient;
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->flushCommands();
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
465ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() {
466631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    return mInitCheck == NO_ERROR;
467ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
468ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
469a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopianstatus_t Surface::validate(bool inCancelBuffer) const
470076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
471631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // check that we initialized ourself properly
472631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (mInitCheck != NO_ERROR) {
473579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        LOGE("invalid token (identity=%u)", mIdentity);
474631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        return mInitCheck;
47540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
476631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
477631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // verify the identity of this surface
4787e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    uint32_t identity = mSharedBufferClient->getIdentity();
479631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (mIdentity != identity) {
480579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        LOGE("[Surface] using an invalid surface, "
481631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian                "identity=%u should be %d",
482579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                mIdentity, identity);
483e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        CallStack stack;
484e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.update();
485e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.dump("Surface");
486a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian        return BAD_INDEX;
487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
488631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
489631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // check the surface didn't become invalid
4907e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    status_t err = mSharedBufferClient->getStatus();
491076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR) {
492a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian        if (!inCancelBuffer) {
493a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian            LOGE("surface (identity=%u) is invalid, err=%d (%s)",
494a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian                    mIdentity, err, strerror(-err));
495a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian            CallStack stack;
496a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian            stack.update();
497a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian            stack.dump("Surface");
498a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian        }
499076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
501631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
503076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
504076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
505631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopiansp<ISurface> Surface::getISurface() const {
506631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    return mSurface;
507631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian}
508631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5114b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::setSwapInterval(ANativeWindow* window, int interval) {
512076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
514076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5154b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::dequeueBuffer(ANativeWindow* window,
516cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t** buffer) {
517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
518076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->dequeueBuffer(buffer);
519076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
520076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
52119957553cbda9134f542e3374c28710d3556d1ceMathias Agopianint Surface::cancelBuffer(ANativeWindow* window,
52219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        android_native_buffer_t* buffer) {
52319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    Surface* self = getSelf(window);
52419957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    return self->cancelBuffer(buffer);
52519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian}
52619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
5274b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::lockBuffer(ANativeWindow* window,
528cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
529076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
530076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->lockBuffer(buffer);
531076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
532076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5334b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::queueBuffer(ANativeWindow* window,
534cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
535076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
536076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->queueBuffer(buffer);
537076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5394b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::query(ANativeWindow* window,
540cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int what, int* value) {
541cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    Surface* self = getSelf(window);
542cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return self->query(what, value);
543cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
544cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
5454b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::perform(ANativeWindow* window,
546cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int operation, ...) {
5475221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_list args;
5485221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_start(args, operation);
5495221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    Surface* self = getSelf(window);
5505221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = self->perform(operation, args);
5515221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_end(args);
5525221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
5535221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
5545221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
555076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::needNewBuffer(int bufIdx,
558a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pWidth, uint32_t *pHeight,
559a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const
560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
562a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // Always call needNewBuffer(), since it clears the needed buffers flags
564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
565a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
566a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool newNeewBuffer = needNewBuffer || !validBuffer;
567a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (newNeewBuffer) {
568a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
569a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
570a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return newNeewBuffer;
571a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
572a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer)
574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
575963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
57935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog& logger(GraphicLog::getInstance());
58035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
58135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
582cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t bufIdx = mSharedBufferClient->dequeue();
58335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
58435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
58535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
586cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (bufIdx < 0) {
587cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
588cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return bufIdx;
58904bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian    }
59068a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian
591a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // grow the buffer array if needed
592a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t size = mBuffers.size();
593a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t needed = bufIdx+1;
594a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (size < needed) {
595a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBuffers.insertAt(size, needed-size);
596a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
5973a8069566724c87d1a88843e6430439e5d2a2e33Mathias Agopian
598a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, format, usage;
599a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
600a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        err = getBufferLocked(bufIdx, w, h, format, usage);
601a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
602a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                bufIdx, w, h, format, usage, strerror(-err));
60350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (err == NO_ERROR) {
60450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            // reset the width/height with the what we get from the buffer
605a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
60650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mWidth  = uint32_t(backBuffer->width);
60750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mHeight = uint32_t(backBuffer->height);
60850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        }
609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
611cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // if we still don't have a buffer here, we probably ran out of memory
612a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
613cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (!err && backBuffer==0) {
614cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = NO_MEMORY;
615cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
616cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
617cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    if (err == NO_ERROR) {
618cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mDirtyRegion.set(backBuffer->width, backBuffer->height);
619cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *buffer = backBuffer.get();
620cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
621cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mSharedBufferClient->undoDequeue(bufIdx);
622cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    }
62350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
624cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    return err;
625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
62719957553cbda9134f542e3374c28710d3556d1ceMathias Agopianint Surface::cancelBuffer(android_native_buffer_t* buffer)
62819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian{
629a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian    status_t err = validate(true);
63019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    switch (err) {
63119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    case NO_ERROR:
63219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // no error, common case
63319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        break;
634a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopian    case BAD_INDEX:
63519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // legitimate errors here
63619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        return err;
63719957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    default:
63819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // other errors happen because the surface is now invalid,
63919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // for instance because it has been destroyed. In this case,
64019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // we just fail silently (canceling a buffer is not technically
64119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // an error at this point)
64219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        return NO_ERROR;
64319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    }
64419957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
64519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
64619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
64719957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    err = mSharedBufferClient->cancel(bufIdx);
64819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
64919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
65019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    return err;
65119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian}
65219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
65319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
654076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer)
655076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
656963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
65740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (err != NO_ERROR)
65840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return err;
65940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
660b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
66135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
66235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog& logger(GraphicLog::getInstance());
66335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
66435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
665cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->lock(bufIdx);
66635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
66735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
66835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
669cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
670cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer)
67435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian{
675963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
676076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
677076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
678076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
6790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (mSwapRectangle.isValid()) {
6800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        mDirtyRegion.set(mSwapRectangle);
6810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
6820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
683b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
68435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
68535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
68635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
687b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
688cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
689cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
690cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->queue(bufIdx);
691cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
692076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
693cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR) {
694b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        // TODO: can we avoid this IPC if we know there is one pending?
695b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mClient.signalServer();
696cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
698076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
699076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
700cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value)
701cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{
702cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    switch (what) {
703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_WIDTH:
704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mWidth);
705cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
706cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_HEIGHT:
707cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mHeight);
708cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
709cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_FORMAT:
710cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mFormat);
711cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
7129d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
7139d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis        *value = MIN_UNDEQUEUED_BUFFERS;
7149d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis        return NO_ERROR;
715391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
716134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
717134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        *value = sf->authenticateSurface(mSurface) ? 1 : 0;
718134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        return NO_ERROR;
719cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    }
720391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis    case NATIVE_WINDOW_CONCRETE_TYPE:
721391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis        *value = NATIVE_WINDOW_SURFACE;
722391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis        return NO_ERROR;
723391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis    }
724cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return BAD_VALUE;
725cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
726cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
7275221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args)
7285221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{
729cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    status_t err = validate();
730cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    if (err != NO_ERROR)
731cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        return err;
732cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
7335221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = NO_ERROR;
7345221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    switch (operation) {
73555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_SET_USAGE:
73655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        dispatch_setUsage( args );
73755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
73855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_CONNECT:
73955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_connect( args );
74055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
74155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_DISCONNECT:
74255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_disconnect( args );
74355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
744cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    case NATIVE_WINDOW_SET_CROP:
745cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        res = dispatch_crop( args );
746cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        break;
747f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    case NATIVE_WINDOW_SET_BUFFER_COUNT:
748f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        res = dispatch_set_buffer_count( args );
749f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        break;
75038ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
75138ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        res = dispatch_set_buffers_geometry( args );
75238ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        break;
753b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
754b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        res = dispatch_set_buffers_transform( args );
755b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        break;
75655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    default:
75755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = NAME_NOT_FOUND;
75855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
7595221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    }
7605221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
7615221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
7625221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
76355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianvoid Surface::dispatch_setUsage(va_list args) {
76455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int usage = va_arg(args, int);
76555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    setUsage( usage );
76655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
76755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_connect(va_list args) {
76855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
76955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return connect( api );
77055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
77155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_disconnect(va_list args) {
77255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
77355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return disconnect( api );
77455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
775cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::dispatch_crop(va_list args) {
776cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
777cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return crop( reinterpret_cast<Rect const*>(rect) );
778cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
779f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopianint Surface::dispatch_set_buffer_count(va_list args) {
780f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    size_t bufferCount = va_arg(args, size_t);
781f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    return setBufferCount(bufferCount);
782f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian}
783a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::dispatch_set_buffers_geometry(va_list args) {
784a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int w = va_arg(args, int);
785a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int h = va_arg(args, int);
786a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int f = va_arg(args, int);
787a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return setBuffersGeometry(w, h, f);
788a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
78955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
790b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopianint Surface::dispatch_set_buffers_transform(va_list args) {
791b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    int transform = va_arg(args, int);
792b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    return setBuffersTransform(transform);
793b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian}
794b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
795ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage)
796ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{
797ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
798a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(reqUsage);
799ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
800ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
80155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::connect(int api)
80255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
80355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
80455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
80555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
80655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
80755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected) {
80855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
80955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
81055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = api;
81155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
81255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
81355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
81455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
81555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
81655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
81755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
81855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
81955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
82055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::disconnect(int api)
82155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
82255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
82355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
82455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
82555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
82655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected == api) {
82755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = 0;
82855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
82955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
83055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
83155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
83255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
83355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
83455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
83555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
83655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
83755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
83855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
839cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::crop(Rect const* rect)
840cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian{
841cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
842cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    // TODO: validate rect size
84368f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis
84468f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis    if (rect == NULL || rect->isEmpty()) {
84568f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis        mNextBufferCrop = Rect(0,0);
84668f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis    } else {
84768f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis        mNextBufferCrop = *rect;
84868f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis    }
84968f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis
850cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return NO_ERROR;
851cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
852cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
853b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianint Surface::setBufferCount(int bufferCount)
854b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
855b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<ISurface> s(mSurface);
856b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (s == 0) return NO_INIT;
857b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
858bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
859bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<ISurface> surface;
860bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        virtual status_t operator()(int bufferCount) const {
861bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            return surface->setBufferCount(bufferCount);
862bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
863bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    public:
864bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
865bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } ipc(s);
866b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
867bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
868b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
869b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian            bufferCount, strerror(-err));
87054cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
87154cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (err == NO_ERROR) {
87254cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Clear out any references to the old buffers.
87354cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBuffers.clear();
87454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
87554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
876b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
877b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
878b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
879a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::setBuffersGeometry(int w, int h, int format)
880a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
881a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (w<0 || h<0 || format<0)
882a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
883a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
884a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((w && !h) || (!w && h))
885a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
886a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
887a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
888367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    if (mConnected == NATIVE_WINDOW_API_EGL) {
889367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        return INVALID_OPERATION;
890367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    }
891367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian
892a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(w, h, format);
893367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    if (format != 0) {
894367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // we update the format of the surface as reported by query().
895367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // this is to allow applications to change the format of a surface's
896367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // buffer, and have it reflected in EGL; which is needed for
897367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // EGLConfig validation.
898367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        mFormat = format;
899367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    }
90068f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis
90168f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis    mNextBufferCrop = Rect(0,0);
90268f9127e88ca6fd849d0f28bcd8776e04aab22e6Jamie Gennis
903a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return NO_ERROR;
904a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
905a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
906b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopianint Surface::setBuffersTransform(int transform)
907b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian{
908b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
909b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mNextBufferTransform = transform;
910b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    return NO_ERROR;
911b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian}
912b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
913a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
914a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
915a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::getConnectedApi() const
916a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
917a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
918a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mConnected;
919a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
92055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
921076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
922076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) {
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return Surface::lock(info, NULL, blocking);
925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
928076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
92955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    if (getConnectedApi()) {
93055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        LOGE("Surface::lock(%p) failed. Already connected to another API",
9314b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn                (ANativeWindow*)this);
93255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        CallStack stack;
93355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.update();
93455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
93555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        return INVALID_OPERATION;
93655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
93755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
938cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mApiLock.tryLock() != NO_ERROR) {
9399014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("calling Surface::lock from different threads!");
940cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        CallStack stack;
941cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        stack.update();
94255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
943cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return WOULD_BLOCK;
944cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
9459014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
9469014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    /* Here we're holding mApiLock */
947cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
9489014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    if (mLockedBuffer != 0) {
9499014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::lock failed, already locked");
9509014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        mApiLock.unlock();
9519014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
9529014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    }
9539014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
9545221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    // we're intending to do software rendering from this point
955ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
956ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
957b296533607232357597b255679db29470ab5925dMathias Agopian    android_native_buffer_t* out;
958b296533607232357597b255679db29470ab5925dMathias Agopian    status_t err = dequeueBuffer(&out);
959cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
960076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == NO_ERROR) {
961b296533607232357597b255679db29470ab5925dMathias Agopian        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
962cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = lockBuffer(backBuffer.get());
963cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
964b296533607232357597b255679db29470ab5925dMathias Agopian                getBufferIndex(backBuffer), strerror(-err));
965076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
966076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const Rect bounds(backBuffer->width, backBuffer->height);
967245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const Region boundsRegion(bounds);
968245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            Region scratch(boundsRegion);
9690926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
970245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            newDirtyRegion &= boundsRegion;
971076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
972245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // figure out if we can copy the frontbuffer back
9733330b203039dea366d4981db1408a460134b2d2cMathias Agopian            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
974245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const bool canCopyBack = (frontBuffer != 0 &&
975245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->width  == frontBuffer->width &&
976245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->height == frontBuffer->height &&
977245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->format == frontBuffer->format &&
978245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
979245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
980245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // the dirty region we report to surfaceflinger is the one
981245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // given by the user (as opposed to the one *we* return to the
982245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // user).
983245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            mDirtyRegion = newDirtyRegion;
984245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
985245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            if (canCopyBack) {
986245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // copy the area that is invalid and not repainted this round
987245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
988245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                if (!copyback.isEmpty())
989cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    copyBlt(backBuffer, frontBuffer, copyback);
990245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            } else {
991245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // if we can't copy-back anything, modify the user's dirty
992245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // region to make sure they redraw the whole buffer
993245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                newDirtyRegion = boundsRegion;
994076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
995cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
996245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // keep track of the are of the buffer that is "clean"
997245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // (ie: that will be redrawn)
9980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mOldDirtyRegion = newDirtyRegion;
999076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1000e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            void* vaddr;
10010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            status_t res = backBuffer->lock(
10020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1003e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                    newDirtyRegion.bounds(), &vaddr);
10040926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1005cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            LOGW_IF(res, "failed locking buffer (handle = %p)",
1006cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    backBuffer->handle);
10070926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
10080926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mLockedBuffer = backBuffer;
10090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->w      = backBuffer->width;
10100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->h      = backBuffer->height;
10110926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->s      = backBuffer->stride;
10120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->usage  = backBuffer->usage;
10130926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->format = backBuffer->format;
1014e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            other->bits   = vaddr;
1015076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
1016076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1017cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mApiLock.unlock();
1018076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1020076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1021076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost()
1022076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1023cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mLockedBuffer == 0) {
10249014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::unlockAndPost failed, no locked buffer");
10259014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
1026cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1028cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = mLockedBuffer->unlock();
1029cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
10300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1031cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = queueBuffer(mLockedBuffer.get());
1032cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
1033b296533607232357597b255679db29470ab5925dMathias Agopian            getBufferIndex(mLockedBuffer), strerror(-err));
1034cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1035cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mPostedBuffer = mLockedBuffer;
1036076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer = 0;
1037076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) {
1041ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle = r;
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1045b296533607232357597b255679db29470ab5925dMathias Agopianint Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
1046b296533607232357597b255679db29470ab5925dMathias Agopian{
1047309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    int idx = buffer->getIndex();
1048309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    if (idx < 0) {
1049309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // The buffer doesn't have an index set.  See if the handle the same as
1050309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // one of the buffers for which we do know the index.  This can happen
1051309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
1052309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // was dequeued from an ANativeWindow.
1053e9ebae24b9507f6cbbcd685c3b02761c4f4698c0Jamie Gennis        for (size_t i = 0; i < mBuffers.size(); i++) {
1054bd9cbc3b5547e096eca243c3ec7ebe3ee1ab3b89Jamie Gennis            if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
1055309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis                idx = mBuffers[i]->getIndex();
1056309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis                break;
1057309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            }
1058309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        }
1059309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    }
1060309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    return idx;
1061b296533607232357597b255679db29470ab5925dMathias Agopian}
1062b296533607232357597b255679db29470ab5925dMathias Agopian
1063a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianstatus_t Surface::getBufferLocked(int index,
1064a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1066ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<ISurface> s(mSurface);
1067ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (s == 0) return NO_INIT;
1068ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
1069076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = NO_MEMORY;
107050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
107150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    // free the current buffer
1072a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
107350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (currentBuffer != 0) {
107450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        currentBuffer.clear();
107550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    }
107650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
1077a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
1078cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(buffer==0,
1079cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "ISurface::getBuffer(%d, %08x) returned NULL",
1080cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            index, usage);
1081309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    if (buffer != 0) { // this should always happen by construction
1082cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(buffer->handle == NULL,
1083a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
1084a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "returned a buffer with a null handle",
1085a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                mIdentity, index, w, h, format, usage);
10860b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        err = mSharedBufferClient->getStatus();
10870b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
10880b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        if (!err && buffer->handle != NULL) {
1089309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            currentBuffer = buffer;
1090309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            currentBuffer->setIndex(index);
1091d3144beec6acb37702629799a2adbeccc72ca222Mathias Agopian        } else {
1092f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian            err = err<0 ? err : status_t(NO_MEMORY);
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1095076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1098a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
1099a138f89c5e78b7e8994823e97d6e860869762837Mathias AgopianSurface::BufferInfo::BufferInfo()
1100a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    : mWidth(0), mHeight(0), mFormat(0),
1101a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian      mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
1102a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
1103a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1104a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1105a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
1106a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
1107a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mWidth = w;
1108a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mHeight = h;
1109a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mFormat = format;
1110a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty |= GEOMETRY;
1111a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
1112a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1113a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1114a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t usage) {
1115a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mUsage = usage;
1116a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1117a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1118a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
1119a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const {
1120a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pWidth  = mWidth;
1121a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pHeight = mHeight;
1122a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pFormat = mFormat;
1123a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pUsage  = mUsage;
1124a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1125a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1126a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
1127a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // make sure we AT LEAST have the usage flags we want
1128a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (mDirty || buffer==0 ||
1129a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            ((buffer->usage & mUsage) != mUsage)) {
1130a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty = 0;
1131a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return false;
1132a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
1133a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return true;
1134a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1135a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1136a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1138