Surface.cpp revision a0c30e924193da57723fd53b710ce6be24fb26f5
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>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
379cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h>
389cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurface.h>
399cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurfaceComposer.h>
409cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/SurfaceComposerClient.h>
41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
429cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/SharedBufferStack.h>
439cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/LayerState.h>
44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------
48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
4914998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt(
503330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const sp<GraphicBuffer>& dst,
513330b203039dea366d4981db1408a460134b2d2cMathias Agopian        const sp<GraphicBuffer>& src,
520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        const Region& reg)
53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
54245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    // src and dst with, height and format must be identical. no verification
55245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian    // is done here.
5614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    status_t err;
5714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t const * src_bits = NULL;
5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
5914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
6114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t* dst_bits = NULL;
6214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator head(reg.begin());
6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator tail(reg.end());
6714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (head != tail && src_bits && dst_bits) {
68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t bpp = bytesPerPixel(src->format);
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t dbpr = dst->stride * bpp;
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t sbpr = src->stride * bpp;
710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        while (head != tail) {
7314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian            const Rect& r(*head++);
740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ssize_t h = r.height();
750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (h <= 0) continue;
760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            size_t size = r.width() * bpp;
770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (dbpr==sbpr && size==sbpr) {
800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                size *= h;
810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                h = 1;
82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            do {
840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                memcpy(d, s, size);
850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                d += dbpr;
860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                s += sbpr;
870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            } while (--h > 0);
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
9114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (src_bits)
9214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        src->unlock();
9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (dst_bits)
9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        dst->unlock();
9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    return err;
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
10062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian//  SurfaceControl
10262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
10401b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl(
10501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceComposerClient>& client,
10662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const sp<ISurface>& surface,
1077e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian        const ISurfaceComposerClient::surface_data_t& data,
10818d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
10962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    : mClient(client), mSurface(surface),
11062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian      mToken(data.token), mIdentity(data.identity),
1111c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mWidth(data.width), mHeight(data.height), mFormat(data.format),
1121c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mFlags(flags)
11362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
11518d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian
11662185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl()
11762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
11962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
12062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy()
12262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
12318d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian    if (isValid()) {
12462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        mClient->destroySurface(mToken);
12562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
12662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // clear all references and trigger an IPC now, to make sure things
12862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // happen without delay, since these resources are quite heavy.
12962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mClient.clear();
13062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurface.clear();
13162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    IPCThreadState::self()->flushCommands();
13262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
13362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
13462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear()
13562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
13662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // here, the window manager tells us explicitly that we should destroy
13762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // the surface's resource. Soon after this call, it will also release
13862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // its last reference (which will call the dtor); however, it is possible
13962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // that a client living in the same process still holds references which
14062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // would delay the call to the dtor -- that is why we need this explicit
14162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // "clear()" call.
14262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
14362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
14462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
14501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface(
14601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
14701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
14801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (lhs == 0 || rhs == 0)
14901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        return false;
15001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
15101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
15201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
15362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) {
154963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
15562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
156631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setLayer(mToken, layer);
15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) {
160963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
162631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setPosition(mToken, x, y);
16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
166963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
168631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
16962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setSize(mToken, w, h);
17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() {
172963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
174631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->hide(mToken);
17662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) {
178963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
180631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->show(mToken, layer);
18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() {
184963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
186631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->freeze(mToken);
18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() {
190963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
192631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->unfreeze(mToken);
19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
196963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
198631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFlags(mToken, flags, mask);
20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
202963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
204631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setTransparentRegionHint(mToken, transparent);
20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) {
208963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
210631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setAlpha(mToken, alpha);
21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
214963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
216631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
21862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) {
220963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
222631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFreezeTint(mToken, tint);
22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
226963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t SurfaceControl::validate() const
22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mToken<0 || mClient==0) {
22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, mClient.get());
23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return NO_ERROR;
23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
23601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel(
23701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& control, Parcel* parcel)
23801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
23901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t flags = 0;
24001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t format = 0;
24101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t identity = 0;
242cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t width = 0;
243cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t height = 0;
24401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<SurfaceComposerClient> client;
24501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<ISurface> sur;
24601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (SurfaceControl::isValid(control)) {
24701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        identity = control->mIdentity;
24801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        client   = control->mClient;
24901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        sur      = control->mSurface;
250cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        width    = control->mWidth;
251cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        height   = control->mHeight;
25201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        format   = control->mFormat;
25301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        flags    = control->mFlags;
25401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
25601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(identity);
257cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(width);
258cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(height);
25901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(format);
26001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(flags);
26101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return NO_ERROR;
26201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
26301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const
26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    Mutex::Autolock _l(mLock);
26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (mSurfaceData == 0) {
26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return mSurfaceData;
27101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
27201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
274076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian//  Surface
275076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianclass SurfaceClient : public Singleton<SurfaceClient>
278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    // all these attributes are constants
280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposer> mComposerService;
281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<ISurfaceComposerClient> mClient;
282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t mStatus;
283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedClient* mControl;
284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    sp<IMemoryHeap> mControlMemory;
285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SurfaceClient()
287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        : Singleton<SurfaceClient>(), mStatus(NO_INIT)
288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    {
289b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mComposerService = sf;
291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mClient = sf->createClientConnection();
292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (mClient != NULL) {
293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mControlMemory = mClient->getControlBlock();
294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            if (mControlMemory != NULL) {
295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                mControl = static_cast<SharedClient *>(
296b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                        mControlMemory->getBase());
297b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                if (mControl) {
298b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                    mStatus = NO_ERROR;
299b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                }
300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            }
301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    friend class Singleton<SurfaceClient>;
304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianpublic:
305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    status_t initCheck() const {
306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mStatus;
307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    SharedClient* getSharedClient() const {
309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mControl;
310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        // TODO: we could cache a few tokens here to avoid an IPC
313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        return mClient->getTokenForSurface(sur);
314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    void signalServer() const {
316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mComposerService->signal();
317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    }
318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian};
319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
322b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
323b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
32401b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface)
325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mBufferMapper(GraphicBufferMapper::get()),
326b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mClient(SurfaceClient::getInstance()),
327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSharedBufferClient(NULL),
328631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian      mInitCheck(NO_INIT),
329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSurface(surface->mSurface),
330b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mIdentity(surface->mIdentity),
331b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mFormat(surface->mFormat), mFlags(surface->mFlags),
332ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian      mWidth(surface->mWidth), mHeight(surface->mHeight)
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
33401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
33501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
33662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
337a0c30e924193da57723fd53b710ce6be24fb26f5Mathias AgopianSurface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    : mBufferMapper(GraphicBufferMapper::get()),
339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mClient(SurfaceClient::getInstance()),
340b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mSharedBufferClient(NULL),
341b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian      mInitCheck(NO_INIT)
34201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
343a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    mSurface    = interface_cast<ISurface>(ref);
34401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mIdentity   = parcel.readInt32();
345cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mWidth      = parcel.readInt32();
346cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mHeight     = parcel.readInt32();
34701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFormat     = parcel.readInt32();
34801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFlags      = parcel.readInt32();
34901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
35001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
35101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
352a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopiansp<Surface> Surface::readFromParcel(
353a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian        const Parcel& data, const sp<Surface>& other)
354a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian{
355a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    sp<Surface> result(other);
356a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    sp<IBinder> binder(data.readStrongBinder());
357a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    if (other==0 || binder != other->mSurface->asBinder()) {
358a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian        result = new Surface(data, binder);
359a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    }
360a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian    return result;
361a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian}
362a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian
36301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init()
36401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
365076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::setSwapInterval  = setSwapInterval;
366076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::dequeueBuffer    = dequeueBuffer;
367076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::lockBuffer       = lockBuffer;
368076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::queueBuffer      = queueBuffer;
369cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    android_native_window_t::query            = query;
3705221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    android_native_window_t::perform          = perform;
371631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    DisplayInfo dinfo;
373076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
374076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
375076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
376076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: set real values here
377076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
378076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
379076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
380631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
38155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    mConnected = 0;
382631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    mSwapRectangle.makeInvalid();
383a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // two buffers by default
384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.setCapacity(2);
385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.insertAt(0, 2);
386631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
387b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
388b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mToken = mClient.getTokenForSurface(mSurface);
389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        if (mToken >= 0) {
390b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mSharedBufferClient = new SharedBufferClient(
391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian                    mClient.getSharedClient(), mToken, 2, mIdentity);
392b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian            mInitCheck = mClient.getSharedClient()->validate(mToken);
393b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        }
394631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    }
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface()
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
39940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // this is a client-side operation, the surface is destroyed, unmap
40040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // its buffers in this process.
401a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    size_t size = mBuffers.size();
402a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    for (size_t i=0 ; i<size ; i++) {
40350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
40421c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
40540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        }
40640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
40740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
40840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // clear all references and trigger an IPC now, to make sure things
40940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // happen without delay, since these resources are quite heavy.
410a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBuffers.clear();
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurface.clear();
412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    delete mSharedBufferClient;
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->flushCommands();
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
416ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() {
417631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    return mInitCheck == NO_ERROR;
418ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
419ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
420963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t Surface::validate() const
421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
422631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // check that we initialized ourself properly
423631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (mInitCheck != NO_ERROR) {
424b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        LOGE("invalid token (%d, identity=%u)", mToken, mIdentity);
425631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        return mInitCheck;
42640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
427631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
428631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // verify the identity of this surface
4297e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    uint32_t identity = mSharedBufferClient->getIdentity();
430631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
431631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // this is a bit of a (temporary) special case, identity==0 means that
432631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // no operation are allowed from the client (eg: dequeue/queue), this
433631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // is used with PUSH_BUFFER surfaces for instance
434631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (identity == 0) {
435631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
436631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        return INVALID_OPERATION;
437631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    }
438631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
439631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    if (mIdentity != identity) {
440631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian        LOGE("[Surface] using an invalid surface id=%d, "
441631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian                "identity=%u should be %d",
442631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian                mToken, mIdentity, identity);
443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
445631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
446631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    // check the surface didn't become invalid
4477e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    status_t err = mSharedBufferClient->getStatus();
448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR) {
449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                mToken, mIdentity, err, strerror(-err));
451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
453631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
454076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
457631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopiansp<ISurface> Surface::getISurface() const {
458631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian    return mSurface;
459631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian}
460631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian
461076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
462076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
463cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) {
464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
465076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
466076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
467076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window,
468cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t** buffer) {
469076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
470076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->dequeueBuffer(buffer);
471076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window,
474cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->lockBuffer(buffer);
477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
478076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
479076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window,
480cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
482076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->queueBuffer(buffer);
483076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
484076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
485cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(android_native_window_t* window,
486cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int what, int* value) {
487cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    Surface* self = getSelf(window);
488cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return self->query(what, value);
489cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
490cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
4915221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(android_native_window_t* window,
492cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int operation, ...) {
4935221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_list args;
4945221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_start(args, operation);
4955221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    Surface* self = getSelf(window);
4965221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = self->perform(operation, args);
4975221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_end(args);
4985221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
4995221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
5005221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
503a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::needNewBuffer(int bufIdx,
504a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pWidth, uint32_t *pHeight,
505a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const
506a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
507a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
508a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
509a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // Always call needNewBuffer(), since it clears the needed buffers flags
510a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
511a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
512a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    bool newNeewBuffer = needNewBuffer || !validBuffer;
513a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (newNeewBuffer) {
514a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
515a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
516a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return newNeewBuffer;
517a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
518a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
519076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer)
520076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
521963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
522076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
523076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t bufIdx = mSharedBufferClient->dequeue();
526cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (bufIdx < 0) {
527cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
528cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return bufIdx;
52904bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian    }
53068a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian
531a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // grow the buffer array if needed
532a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t size = mBuffers.size();
533a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const size_t needed = bufIdx+1;
534a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (size < needed) {
535a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mBuffers.insertAt(size, needed-size);
536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
5373a8069566724c87d1a88843e6430439e5d2a2e33Mathias Agopian
538a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    uint32_t w, h, format, usage;
539a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
540a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        err = getBufferLocked(bufIdx, w, h, format, usage);
541a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
542a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                bufIdx, w, h, format, usage, strerror(-err));
54350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (err == NO_ERROR) {
54450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            // reset the width/height with the what we get from the buffer
545a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
54650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mWidth  = uint32_t(backBuffer->width);
54750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mHeight = uint32_t(backBuffer->height);
54850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        }
549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
550076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
551cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // if we still don't have a buffer here, we probably ran out of memory
552a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (!err && backBuffer==0) {
554cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = NO_MEMORY;
555cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
556cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
557cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    if (err == NO_ERROR) {
558cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mDirtyRegion.set(backBuffer->width, backBuffer->height);
559cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *buffer = backBuffer.get();
560cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
561cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mSharedBufferClient->undoDequeue(bufIdx);
562cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    }
56350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
564cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    return err;
565076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer)
568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
569963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
57040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (err != NO_ERROR)
57140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return err;
57240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
573b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
574cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->lock(bufIdx);
575cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer)
580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
581963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian    status_t err = validate();
582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (mSwapRectangle.isValid()) {
5860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        mDirtyRegion.set(mSwapRectangle);
5870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
5880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
589b296533607232357597b255679db29470ab5925dMathias Agopian    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
590cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
591cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
592cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->queue(bufIdx);
593cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
595cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR) {
596b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        // TODO: can we avoid this IPC if we know there is one pending?
597b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mClient.signalServer();
598cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
599cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
602cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value)
603cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{
604cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    switch (what) {
605cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_WIDTH:
606cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mWidth);
607cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
608cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_HEIGHT:
609cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mHeight);
610cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
611cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_FORMAT:
612cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mFormat);
613cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
614cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    }
615cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return BAD_VALUE;
616cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
617cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
6185221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args)
6195221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{
620cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    status_t err = validate();
621cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    if (err != NO_ERROR)
622cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        return err;
623cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
6245221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = NO_ERROR;
6255221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    switch (operation) {
62655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_SET_USAGE:
62755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        dispatch_setUsage( args );
62855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
62955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_CONNECT:
63055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_connect( args );
63155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
63255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    case NATIVE_WINDOW_DISCONNECT:
63355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = dispatch_disconnect( args );
63455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
635cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    case NATIVE_WINDOW_SET_CROP:
636cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        res = dispatch_crop( args );
637cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian        break;
638f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    case NATIVE_WINDOW_SET_BUFFER_COUNT:
639f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        res = dispatch_set_buffer_count( args );
640f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian        break;
64138ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
64238ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        res = dispatch_set_buffers_geometry( args );
64338ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian        break;
64455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    default:
64555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        res = NAME_NOT_FOUND;
64655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        break;
6475221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    }
6485221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
6495221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
6505221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
65155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianvoid Surface::dispatch_setUsage(va_list args) {
65255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int usage = va_arg(args, int);
65355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    setUsage( usage );
65455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
65555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_connect(va_list args) {
65655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
65755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return connect( api );
65855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
65955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_disconnect(va_list args) {
66055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int api = va_arg(args, int);
66155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return disconnect( api );
66255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
663cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::dispatch_crop(va_list args) {
664cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
665cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return crop( reinterpret_cast<Rect const*>(rect) );
666cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
667f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopianint Surface::dispatch_set_buffer_count(va_list args) {
668f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    size_t bufferCount = va_arg(args, size_t);
669f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian    return setBufferCount(bufferCount);
670f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian}
671a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::dispatch_set_buffers_geometry(va_list args) {
672a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int w = va_arg(args, int);
673a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int h = va_arg(args, int);
674a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    int f = va_arg(args, int);
675a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return setBuffersGeometry(w, h, f);
676a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
67755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
678ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage)
679ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{
680ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
681a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(reqUsage);
682ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
683ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
68455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::connect(int api)
68555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
68655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
68755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
68855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
68955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
69055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected) {
69155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
69255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
69355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = api;
69455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
69555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
69655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
69755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
69855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
69955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
70055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
70155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
70255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
70355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::disconnect(int api)
70455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{
70555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
70655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    int err = NO_ERROR;
70755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    switch (api) {
70855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        case NATIVE_WINDOW_API_EGL:
70955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            if (mConnected == api) {
71055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                mConnected = 0;
71155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            } else {
71255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                err = -EINVAL;
71355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            }
71455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
71555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        default:
71655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            err = -EINVAL;
71755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian            break;
71855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
71955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    return err;
72055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian}
72155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
722cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::crop(Rect const* rect)
723cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian{
724cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
725cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    // TODO: validate rect size
726cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    mNextBufferCrop = *rect;
727cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian    return NO_ERROR;
728cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian}
729cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian
730b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianint Surface::setBufferCount(int bufferCount)
731b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
732b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    sp<ISurface> s(mSurface);
733b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    if (s == 0) return NO_INIT;
734b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
735bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
736bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        sp<ISurface> surface;
737bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        virtual status_t operator()(int bufferCount) const {
738bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian            return surface->setBufferCount(bufferCount);
739bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        }
740bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    public:
741bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
742bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    } ipc(s);
743b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
744bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
745b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
746b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian            bufferCount, strerror(-err));
747b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    return err;
748b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
749b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
750a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::setBuffersGeometry(int w, int h, int format)
751a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
752a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (w<0 || h<0 || format<0)
753a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
754a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
755a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((w && !h) || (!w && h))
756a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return BAD_VALUE;
757a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
758a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
759a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mBufferInfo.set(w, h, format);
760a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return NO_ERROR;
761a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
762a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
763a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
764a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
765a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::getConnectedApi() const
766a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
767a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
768a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return mConnected;
769a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
77055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
771076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) {
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return Surface::lock(info, NULL, blocking);
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
77955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    if (getConnectedApi()) {
78055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        LOGE("Surface::lock(%p) failed. Already connected to another API",
78155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian                (android_native_window_t*)this);
78255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        CallStack stack;
78355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.update();
78455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
78555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        return INVALID_OPERATION;
78655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian    }
78755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian
788cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mApiLock.tryLock() != NO_ERROR) {
7899014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("calling Surface::lock from different threads!");
790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        CallStack stack;
791cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        stack.update();
79255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian        stack.dump("");
793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return WOULD_BLOCK;
794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
7959014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
7969014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    /* Here we're holding mApiLock */
797cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7989014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    if (mLockedBuffer != 0) {
7999014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::lock failed, already locked");
8009014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        mApiLock.unlock();
8019014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
8029014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian    }
8039014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian
8045221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    // we're intending to do software rendering from this point
805ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
806ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
807b296533607232357597b255679db29470ab5925dMathias Agopian    android_native_buffer_t* out;
808b296533607232357597b255679db29470ab5925dMathias Agopian    status_t err = dequeueBuffer(&out);
809cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
810076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == NO_ERROR) {
811b296533607232357597b255679db29470ab5925dMathias Agopian        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
812cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = lockBuffer(backBuffer.get());
813cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
814b296533607232357597b255679db29470ab5925dMathias Agopian                getBufferIndex(backBuffer), strerror(-err));
815076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
816076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const Rect bounds(backBuffer->width, backBuffer->height);
817245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const Region boundsRegion(bounds);
818245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            Region scratch(boundsRegion);
8190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
820245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            newDirtyRegion &= boundsRegion;
821076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
822245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // figure out if we can copy the frontbuffer back
8233330b203039dea366d4981db1408a460134b2d2cMathias Agopian            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
824245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            const bool canCopyBack = (frontBuffer != 0 &&
825245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->width  == frontBuffer->width &&
826245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->height == frontBuffer->height &&
827245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    backBuffer->format == frontBuffer->format &&
828245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
829245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
830245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // the dirty region we report to surfaceflinger is the one
831245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // given by the user (as opposed to the one *we* return to the
832245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // user).
833245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            mDirtyRegion = newDirtyRegion;
834245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian
835245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            if (canCopyBack) {
836245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // copy the area that is invalid and not repainted this round
837245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
838245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                if (!copyback.isEmpty())
839cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    copyBlt(backBuffer, frontBuffer, copyback);
840245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            } else {
841245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // if we can't copy-back anything, modify the user's dirty
842245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                // region to make sure they redraw the whole buffer
843245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian                newDirtyRegion = boundsRegion;
844076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
845cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
846245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // keep track of the are of the buffer that is "clean"
847245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian            // (ie: that will be redrawn)
8480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mOldDirtyRegion = newDirtyRegion;
849076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
850e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            void* vaddr;
8510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            status_t res = backBuffer->lock(
8520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
853e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                    newDirtyRegion.bounds(), &vaddr);
8540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
855cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            LOGW_IF(res, "failed locking buffer (handle = %p)",
856cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    backBuffer->handle);
8570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
8580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mLockedBuffer = backBuffer;
8590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->w      = backBuffer->width;
8600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->h      = backBuffer->height;
8610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->s      = backBuffer->stride;
8620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->usage  = backBuffer->usage;
8630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->format = backBuffer->format;
864e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            other->bits   = vaddr;
865076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
866076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
867cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mApiLock.unlock();
868076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
870076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
871076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost()
872076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
873cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mLockedBuffer == 0) {
8749014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        LOGE("Surface::unlockAndPost failed, no locked buffer");
8759014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian        return INVALID_OPERATION;
876cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
878cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = mLockedBuffer->unlock();
879cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
8800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
881cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = queueBuffer(mLockedBuffer.get());
882cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
883b296533607232357597b255679db29470ab5925dMathias Agopian            getBufferIndex(mLockedBuffer), strerror(-err));
884cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
885cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mPostedBuffer = mLockedBuffer;
886076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer = 0;
887076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) {
891ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle = r;
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
895b296533607232357597b255679db29470ab5925dMathias Agopianint Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
896b296533607232357597b255679db29470ab5925dMathias Agopian{
897b296533607232357597b255679db29470ab5925dMathias Agopian    return buffer->getIndex();
898b296533607232357597b255679db29470ab5925dMathias Agopian}
899b296533607232357597b255679db29470ab5925dMathias Agopian
900a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianstatus_t Surface::getBufferLocked(int index,
901a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
903ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<ISurface> s(mSurface);
904ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (s == 0) return NO_INIT;
905ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
906076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = NO_MEMORY;
90750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
90850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    // free the current buffer
909a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
91050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (currentBuffer != 0) {
91150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        getBufferMapper().unregisterBuffer(currentBuffer->handle);
91250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        currentBuffer.clear();
91350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    }
91450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
915a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
916cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(buffer==0,
917cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "ISurface::getBuffer(%d, %08x) returned NULL",
918cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            index, usage);
91950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (buffer != 0) { // this should never happen by construction
920cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(buffer->handle == NULL,
921a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
922a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                "returned a buffer with a null handle",
923a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian                mIdentity, index, w, h, format, usage);
9240b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        err = mSharedBufferClient->getStatus();
9250b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
9260b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian        if (!err && buffer->handle != NULL) {
92750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            err = getBufferMapper().registerBuffer(buffer->handle);
92850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
92950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian                    err, strerror(-err));
93050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            if (err == NO_ERROR) {
93150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian                currentBuffer = buffer;
932cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                currentBuffer->setIndex(index);
93350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            }
934d3144beec6acb37702629799a2adbeccc72ca222Mathias Agopian        } else {
935f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian            err = err<0 ? err : status_t(NO_MEMORY);
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
938076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
941a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
942a138f89c5e78b7e8994823e97d6e860869762837Mathias AgopianSurface::BufferInfo::BufferInfo()
943a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    : mWidth(0), mHeight(0), mFormat(0),
944a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian      mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
945a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{
946a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
947a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
948a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
949a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
950a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mWidth = w;
951a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mHeight = h;
952a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mFormat = format;
953a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty |= GEOMETRY;
954a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
955a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
956a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
957a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t usage) {
958a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    mUsage = usage;
959a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
960a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
961a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
962a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        uint32_t *pFormat, uint32_t *pUsage) const {
963a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pWidth  = mWidth;
964a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pHeight = mHeight;
965a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pFormat = mFormat;
966a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    *pUsage  = mUsage;
967a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
968a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
969a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
970a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    // make sure we AT LEAST have the usage flags we want
971a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (mDirty || buffer==0 ||
972a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            ((buffer->usage & mUsage) != mUsage)) {
973a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        mDirty = 0;
974a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        return false;
975a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    }
976a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    return true;
977a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
978a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
979a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ----------------------------------------------------------------------------
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
982