Surface.cpp revision 455d18d4c26a823bff62ca14771986cca52d3462
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
469963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t Surface::validate() 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
480631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // this is a bit of a (temporary) special case, identity==0 means that
481631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // no operation are allowed from the client (eg: dequeue/queue), this
482631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // is used with PUSH_BUFFER surfaces for instance
483631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (identity == 0) {
484631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
485631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        return INVALID_OPERATION;
486631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    }
487631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
488631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (mIdentity != identity) {
489579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        LOGE("[Surface] using an invalid surface, "
490631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian                "identity=%u should be %d",
491579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                mIdentity, identity);
492e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        CallStack stack;
493e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.update();
494e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.dump("Surface");
495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
497631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
498631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // check the surface didn't become invalid
4997e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    status_t err = mSharedBufferClient->getStatus();
500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR) {
501579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        LOGE("surface (identity=%u) is invalid, err=%d (%s)",
502579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian                mIdentity, err, strerror(-err));
503e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        CallStack stack;
504e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.update();
505e6f096a4cde5161e9e8432a6f6f2008e6bc710f4Mathias Agopian        stack.dump("Surface");
506076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
507076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
508631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
511076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
512631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopiansp<ISurface> Surface::getISurface() const {
513631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    return mSurface;
514631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian}
515631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5184b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::setSwapInterval(ANativeWindow* window, int interval) {
519076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
520076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
521076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5224b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::dequeueBuffer(ANativeWindow* window,
523cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t** buffer) {
524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
525076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->dequeueBuffer(buffer);
526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
527076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
52819957553cbda9134f542e3374c28710d3556d1ceMathias Agopianint Surface::cancelBuffer(ANativeWindow* window,
52919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        android_native_buffer_t* buffer) {
53019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    Surface* self = getSelf(window);
53119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    return self->cancelBuffer(buffer);
53219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian}
53319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
5344b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::lockBuffer(ANativeWindow* window,
535cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
536076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
537076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->lockBuffer(buffer);
538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5404b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::queueBuffer(ANativeWindow* window,
541cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
542076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->queueBuffer(buffer);
544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5464b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::query(ANativeWindow* window,
547cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int what, int* value) {
548cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    Surface* self = getSelf(window);
549cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return self->query(what, value);
550cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
551cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
5524b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::perform(ANativeWindow* window,
553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int operation, ...) {
5545221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_list args;
5555221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_start(args, operation);
5565221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    Surface* self = getSelf(window);
5575221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = self->perform(operation, args);
5585221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_end(args);
5595221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
5605221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
5615221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
562076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::needNewBuffer(int bufIdx,
565a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pWidth, uint32_t *pHeight,
566a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const
567a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
568a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
569a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
570a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // Always call needNewBuffer(), since it clears the needed buffers flags
571a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
572a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
573a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool newNeewBuffer = needNewBuffer || !validBuffer;
574a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (newNeewBuffer) {
575a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
576a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
577a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return newNeewBuffer;
578a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
579a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer)
581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
582963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
58635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog& logger(GraphicLog::getInstance());
58735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
58835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
589cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t bufIdx = mSharedBufferClient->dequeue();
59035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
59135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
59235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
593cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (bufIdx < 0) {
594cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
595cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return bufIdx;
59604bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian    }
59768a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian
598a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // grow the buffer array if needed
599a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t size = mBuffers.size();
600a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t needed = bufIdx+1;
601a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (size < needed) {
602a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBuffers.insertAt(size, needed-size);
603a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
6043a8069566724c87d1a88843e6430439e5d2a2e33Mathias Agopian
605a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, format, usage;
606a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
607a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        err = getBufferLocked(bufIdx, w, h, format, usage);
608a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
609a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                bufIdx, w, h, format, usage, strerror(-err));
61050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (err == NO_ERROR) {
61150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            // reset the width/height with the what we get from the buffer
612a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
61350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mWidth  = uint32_t(backBuffer->width);
61450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mHeight = uint32_t(backBuffer->height);
61550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        }
616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
617076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
618cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // if we still don't have a buffer here, we probably ran out of memory
619a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
620cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (!err && backBuffer==0) {
621cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = NO_MEMORY;
622cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
624cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    if (err == NO_ERROR) {
625cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mDirtyRegion.set(backBuffer->width, backBuffer->height);
626cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *buffer = backBuffer.get();
627cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
628cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mSharedBufferClient->undoDequeue(bufIdx);
629cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    }
63050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
631cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    return err;
632076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
63419957553cbda9134f542e3374c28710d3556d1ceMathias Agopianint Surface::cancelBuffer(android_native_buffer_t* buffer)
63519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian{
63619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    status_t err = validate();
63719957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    switch (err) {
63819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    case NO_ERROR:
63919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // no error, common case
64019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        break;
64119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    case INVALID_OPERATION:
64219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // legitimate errors here
64319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        return err;
64419957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    default:
64519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // other errors happen because the surface is now invalid,
64619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // for instance because it has been destroyed. In this case,
64719957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // we just fail silently (canceling a buffer is not technically
64819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        // an error at this point)
64919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian        return NO_ERROR;
65019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    }
65119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
65219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
65319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
65419957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    err = mSharedBufferClient->cancel(bufIdx);
65519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
65619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
65719957553cbda9134f542e3374c28710d3556d1ceMathias Agopian    return err;
65819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian}
65919957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
66019957553cbda9134f542e3374c28710d3556d1ceMathias Agopian
661076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer)
662076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
663963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
66440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (err != NO_ERROR)
66540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return err;
66640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
667b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
66835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
66935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog& logger(GraphicLog::getInstance());
67035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
67135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
672cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->lock(bufIdx);
67335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
67435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
67535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
676cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
677cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
680076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer)
68135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian{
682963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
683076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
684076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
685076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
6860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (mSwapRectangle.isValid()) {
6870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        mDirtyRegion.set(mSwapRectangle);
6880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
6890926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
690b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
69135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
69235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
69335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
694b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
695cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
696cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->queue(bufIdx);
698cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
699076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
700cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR) {
701b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        // TODO: can we avoid this IPC if we know there is one pending?
702b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mClient.signalServer();
703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
705076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
706076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
707cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value)
708cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{
709cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    switch (what) {
710cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_WIDTH:
711cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mWidth);
712cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
713cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_HEIGHT:
714cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mHeight);
715cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
716cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_FORMAT:
717cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mFormat);
718cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
719cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    }
720cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return BAD_VALUE;
721cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
722cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
7235221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args)
7245221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{
725cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    status_t err = validate();
726cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    if (err != NO_ERROR)
727cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        return err;
728cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
7295221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = NO_ERROR;
7305221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    switch (operation) {
73155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_SET_USAGE:
73255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        dispatch_setUsage( args );
73355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
73455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_CONNECT:
73555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_connect( args );
73655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
73755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_DISCONNECT:
73855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_disconnect( args );
73955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
740cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    case NATIVE_WINDOW_SET_CROP:
741cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        res = dispatch_crop( args );
742cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        break;
743f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    case NATIVE_WINDOW_SET_BUFFER_COUNT:
744f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        res = dispatch_set_buffer_count( args );
745f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        break;
74638ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
74738ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        res = dispatch_set_buffers_geometry( args );
74838ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        break;
749b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
750b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        res = dispatch_set_buffers_transform( args );
751b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        break;
75255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    default:
75355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = NAME_NOT_FOUND;
75455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
7555221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    }
7565221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
7575221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
7585221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
75955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianvoid Surface::dispatch_setUsage(va_list args) {
76055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int usage = va_arg(args, int);
76155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    setUsage( usage );
76255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
76355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_connect(va_list args) {
76455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
76555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return connect( api );
76655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
76755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_disconnect(va_list args) {
76855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
76955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return disconnect( api );
77055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
771cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::dispatch_crop(va_list args) {
772cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
773cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return crop( reinterpret_cast<Rect const*>(rect) );
774cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
775f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopianint Surface::dispatch_set_buffer_count(va_list args) {
776f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    size_t bufferCount = va_arg(args, size_t);
777f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    return setBufferCount(bufferCount);
778f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian}
779a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::dispatch_set_buffers_geometry(va_list args) {
780a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int w = va_arg(args, int);
781a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int h = va_arg(args, int);
782a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int f = va_arg(args, int);
783a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return setBuffersGeometry(w, h, f);
784a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
78555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
786b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopianint Surface::dispatch_set_buffers_transform(va_list args) {
787b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    int transform = va_arg(args, int);
788b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    return setBuffersTransform(transform);
789b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian}
790b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
791ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage)
792ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{
793ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
794a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(reqUsage);
795ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
796ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
79755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::connect(int api)
79855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
79955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
80055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
80155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
80255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
80355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected) {
80455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
80555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
80655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = api;
80755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
80855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
80955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
81055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
81155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
81255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
81355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
81455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
81555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
81655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::disconnect(int api)
81755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
81855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
81955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
82055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
82155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
82255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected == api) {
82355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = 0;
82455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
82555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
82655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
82755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
82855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
82955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
83055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
83155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
83255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
83355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
83455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
835cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::crop(Rect const* rect)
836cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian{
837b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    // empty/invalid rects are not allowed
838b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    if (rect->isEmpty())
839b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian        return BAD_VALUE;
840b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
841cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
842cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    // TODO: validate rect size
843cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    mNextBufferCrop = *rect;
844cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return NO_ERROR;
845cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
846cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
847b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianint Surface::setBufferCount(int bufferCount)
848b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
849b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<ISurface> s(mSurface);
850b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (s == 0) return NO_INIT;
851b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
852bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
853bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<ISurface> surface;
854bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        virtual status_t operator()(int bufferCount) const {
855bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            return surface->setBufferCount(bufferCount);
856bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
857bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    public:
858bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
859bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } ipc(s);
860b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
861bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
862b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
863b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian            bufferCount, strerror(-err));
86454cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
86554cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    if (err == NO_ERROR) {
86654cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        // Clear out any references to the old buffers.
86754cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis        mBuffers.clear();
86854cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis    }
86954cc83e8a48c57307cdd40fe4b7e296020490095Jamie Gennis
870b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
871b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
872b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
873a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::setBuffersGeometry(int w, int h, int format)
874a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
875a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (w<0 || h<0 || format<0)
876a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
877a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
878a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((w && !h) || (!w && h))
879a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
880a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
881a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
882367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    if (mConnected == NATIVE_WINDOW_API_EGL) {
883367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        return INVALID_OPERATION;
884367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    }
885367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian
886a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(w, h, format);
887367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    if (format != 0) {
888367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // we update the format of the surface as reported by query().
889367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // this is to allow applications to change the format of a surface's
890367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // buffer, and have it reflected in EGL; which is needed for
891367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        // EGLConfig validation.
892367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian        mFormat = format;
893367dc0bd5f0fea8dcf9534d0e6b127dd467adc50Mathias Agopian    }
894a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return NO_ERROR;
895a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
896a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
897b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopianint Surface::setBuffersTransform(int transform)
898b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian{
899b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
900b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    mNextBufferTransform = transform;
901b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian    return NO_ERROR;
902b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian}
903b661d66013b9803c50dc78ca0247ac39caef443aMathias Agopian
904a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
905a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
906a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::getConnectedApi() const
907a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
908a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
909a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mConnected;
910a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
91155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
912076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
913076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) {
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return Surface::lock(info, NULL, blocking);
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
919076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
92055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    if (getConnectedApi()) {
92155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        LOGE("Surface::lock(%p) failed. Already connected to another API",
9224b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn                (ANativeWindow*)this);
92355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        CallStack stack;
92455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.update();
92555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
92655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        return INVALID_OPERATION;
92755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
92855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
929cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mApiLock.tryLock() != NO_ERROR) {
9309014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("calling Surface::lock from different threads!");
931cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        CallStack stack;
932cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        stack.update();
93355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
934cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return WOULD_BLOCK;
935cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
9369014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
9379014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    /* Here we're holding mApiLock */
938cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
9399014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    if (mLockedBuffer != 0) {
9409014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::lock failed, already locked");
9419014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        mApiLock.unlock();
9429014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
9439014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    }
9449014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
9455221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    // we're intending to do software rendering from this point
946ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
947ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
948b296533607232357597b255679db29470ab5925dMathias Agopian    android_native_buffer_t* out;
949b296533607232357597b255679db29470ab5925dMathias Agopian    status_t err = dequeueBuffer(&out);
950cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
951076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == NO_ERROR) {
952b296533607232357597b255679db29470ab5925dMathias Agopian        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
953cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = lockBuffer(backBuffer.get());
954cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
955b296533607232357597b255679db29470ab5925dMathias Agopian                getBufferIndex(backBuffer), strerror(-err));
956076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
957076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const Rect bounds(backBuffer->width, backBuffer->height);
958245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const Region boundsRegion(bounds);
959245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            Region scratch(boundsRegion);
9600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
961245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            newDirtyRegion &= boundsRegion;
962076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
963245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // figure out if we can copy the frontbuffer back
9643330b203039dea366d4981db1408a460134b2d2cMathias Agopian            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
965245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const bool canCopyBack = (frontBuffer != 0 &&
966245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->width  == frontBuffer->width &&
967245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->height == frontBuffer->height &&
968245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->format == frontBuffer->format &&
969245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
970245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
971245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // the dirty region we report to surfaceflinger is the one
972245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // given by the user (as opposed to the one *we* return to the
973245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // user).
974245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            mDirtyRegion = newDirtyRegion;
975245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
976245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            if (canCopyBack) {
977245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // copy the area that is invalid and not repainted this round
978245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
979245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                if (!copyback.isEmpty())
980cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    copyBlt(backBuffer, frontBuffer, copyback);
981245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            } else {
982245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // if we can't copy-back anything, modify the user's dirty
983245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // region to make sure they redraw the whole buffer
984245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                newDirtyRegion = boundsRegion;
985076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
986cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
987245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // keep track of the are of the buffer that is "clean"
988245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // (ie: that will be redrawn)
9890926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mOldDirtyRegion = newDirtyRegion;
990076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
991e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            void* vaddr;
9920926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            status_t res = backBuffer->lock(
9930926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
994e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                    newDirtyRegion.bounds(), &vaddr);
9950926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
996cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            LOGW_IF(res, "failed locking buffer (handle = %p)",
997cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    backBuffer->handle);
9980926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
9990926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mLockedBuffer = backBuffer;
10000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->w      = backBuffer->width;
10010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->h      = backBuffer->height;
10020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->s      = backBuffer->stride;
10030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->usage  = backBuffer->usage;
10040926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->format = backBuffer->format;
1005e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            other->bits   = vaddr;
1006076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
1007076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
1008cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mApiLock.unlock();
1009076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1011076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1012076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost()
1013076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
1014cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mLockedBuffer == 0) {
10159014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::unlockAndPost failed, no locked buffer");
10169014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
1017cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1019cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = mLockedBuffer->unlock();
1020cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
10210926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
1022cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = queueBuffer(mLockedBuffer.get());
1023cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
1024b296533607232357597b255679db29470ab5925dMathias Agopian            getBufferIndex(mLockedBuffer), strerror(-err));
1025cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
1026cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mPostedBuffer = mLockedBuffer;
1027076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer = 0;
1028076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) {
1032ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle = r;
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1036b296533607232357597b255679db29470ab5925dMathias Agopianint Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
1037b296533607232357597b255679db29470ab5925dMathias Agopian{
1038309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    int idx = buffer->getIndex();
1039309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    if (idx < 0) {
1040309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // The buffer doesn't have an index set.  See if the handle the same as
1041309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // one of the buffers for which we do know the index.  This can happen
1042309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
1043309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        // was dequeued from an ANativeWindow.
1044e9ebae24b9507f6cbbcd685c3b02761c4f4698c0Jamie Gennis        for (size_t i = 0; i < mBuffers.size(); i++) {
1045309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            if (buffer->handle == mBuffers[i]->handle) {
1046309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis                idx = mBuffers[i]->getIndex();
1047309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis                break;
1048309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            }
1049309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        }
1050309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    }
1051309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    return idx;
1052b296533607232357597b255679db29470ab5925dMathias Agopian}
1053b296533607232357597b255679db29470ab5925dMathias Agopian
1054a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianstatus_t Surface::getBufferLocked(int index,
1055a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1057ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<ISurface> s(mSurface);
1058ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (s == 0) return NO_INIT;
1059ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
1060076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = NO_MEMORY;
106150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
106250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    // free the current buffer
1063a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
106450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (currentBuffer != 0) {
106550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        currentBuffer.clear();
106650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    }
106750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
1068a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
1069cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(buffer==0,
1070cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "ISurface::getBuffer(%d, %08x) returned NULL",
1071cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            index, usage);
1072309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    if (buffer != 0) { // this should always happen by construction
1073cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(buffer->handle == NULL,
1074a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
1075a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "returned a buffer with a null handle",
1076a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                mIdentity, index, w, h, format, usage);
10770b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        err = mSharedBufferClient->getStatus();
10780b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
10790b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        if (!err && buffer->handle != NULL) {
1080309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            currentBuffer = buffer;
1081309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis            currentBuffer->setIndex(index);
1082d3144beec6acb37702629799a2adbeccc72ca222Mathias Agopian        } else {
1083f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian            err = err<0 ? err : status_t(NO_MEMORY);
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1086076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1089a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
1090a138f89c5e78b7e8994823e97d6e860869762837Mathias AgopianSurface::BufferInfo::BufferInfo()
1091a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    : mWidth(0), mHeight(0), mFormat(0),
1092a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian      mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
1093a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
1094a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1095a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1096a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
1097a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
1098a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mWidth = w;
1099a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mHeight = h;
1100a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mFormat = format;
1101a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty |= GEOMETRY;
1102a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
1103a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1104a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1105a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t usage) {
1106a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mUsage = usage;
1107a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1108a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1109a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
1110a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const {
1111a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pWidth  = mWidth;
1112a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pHeight = mHeight;
1113a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pFormat = mFormat;
1114a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pUsage  = mUsage;
1115a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1116a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1117a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
1118a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // make sure we AT LEAST have the usage flags we want
1119a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (mDirty || buffer==0 ||
1120a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            ((buffer->usage & mUsage) != mUsage)) {
1121a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty = 0;
1122a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return false;
1123a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
1124a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return true;
1125a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1126a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1127a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1129