Surface.cpp revision 62185b7335e85211dc4d0e2003354eb3ea2e66ef
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 <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IPCThreadState.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IMemory.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h>
33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/BufferMapper.h>
34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/EGLNativeWindowSurface.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Surface.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <EGL/android_natives.h>
41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/SharedState.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <pixelflinger/pixelflinger.h>
46076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian//  SurfaceBuffer
51076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
52076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
534243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<class SurfaceBuffer> Mutex Singleton<SurfaceBuffer>::sLock;
544243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<> SurfaceBuffer* Singleton<SurfaceBuffer>::sInstance(0);
554243e666213029a293935987c979831093fb0779Mathias Agopian
56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer()
57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    : BASE(), handle(0), mOwner(false)
58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
59076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    width  =
60076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    height =
61076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    stride =
62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    format =
63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    usage  = 0;
64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_buffer_t::getHandle = getHandle;
65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
66076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer(const Parcel& data)
68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    : BASE(), handle(0), mOwner(true)
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // we own the handle in this case
71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    width  = data.readInt32();
72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    height = data.readInt32();
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    stride = data.readInt32();
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    format = data.readInt32();
75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    usage  = data.readInt32();
76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    handle = data.readNativeHandle();
77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_buffer_t::getHandle = getHandle;
78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::~SurfaceBuffer()
81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (handle && mOwner) {
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        native_handle_close(handle);
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        native_handle_delete(const_cast<native_handle*>(handle));
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint SurfaceBuffer::getHandle(android_native_buffer_t const * base,
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        buffer_handle_t* handle)
90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    *handle = getSelf(base)->handle;
92076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
93076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
94076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceBuffer::writeToParcel(Parcel* reply,
96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        android_native_buffer_t const* buffer)
97076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    buffer_handle_t handle;
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = buffer->getHandle(buffer, &handle);
100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err < 0) {
101076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
102076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
103076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeInt32(buffer->width);
104076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeInt32(buffer->height);
105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeInt32(buffer->stride);
106076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeInt32(buffer->format);
107076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeInt32(buffer->usage);
108076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    reply->writeNativeHandle(handle);
109076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
110076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
111076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
112076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------
113076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
114076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void copyBlt(const android_native_buffer_t* dst,
115076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const android_native_buffer_t* src, const Region& reg)
116076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Region::iterator iterator(reg);
118076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (iterator) {
119076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // NOTE: dst and src must be the same format
120076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        Rect r;
121076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t bpp = bytesPerPixel(src->format);
122076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t dbpr = dst->stride * bpp;
123076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t sbpr = src->stride * bpp;
124076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        while (iterator.iterate(&r)) {
125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            ssize_t h = r.bottom - r.top;
126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (h) {
127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                size_t size = (r.right - r.left) * bpp;
128076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                uint8_t* s = (GGLubyte*)src->bits +
129076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                        (r.left + src->stride * r.top) * bpp;
130076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                uint8_t* d = (GGLubyte*)dst->bits +
131076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                        (r.left + dst->stride * r.top) * bpp;
132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                if (dbpr==sbpr && size==sbpr) {
133076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    size *= h;
134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    h = 1;
135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
136076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                do {
137076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    memcpy(d, s, size);
138076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    d += dbpr;
139076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    s += sbpr;
140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                } while (--h > 0);
141076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
144076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
145076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
14662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
14762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
14862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian//  SurfaceControl
14962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
15062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
15162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
15262185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client,
15362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const sp<ISurface>& surface,
15462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const ISurfaceFlingerClient::surface_data_t& data,
15562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
15662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        bool owner)
15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    : mClient(client), mSurface(surface),
15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian      mToken(data.token), mIdentity(data.identity),
15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian      mFormat(format), mFlags(flags), mOwner(owner)
16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl()
16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
16862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy()
16962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // Destroy the surface in SurfaceFlinger if we were the owner
17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // (in any case, a client won't be able to, because it won't have the
17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // right permission).
17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mOwner && mToken>=0 && mClient!=0) {
17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        mClient->destroySurface(mToken);
17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
17662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // clear all references and trigger an IPC now, to make sure things
17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // happen without delay, since these resources are quite heavy.
17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mClient.clear();
18062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurface.clear();
18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    IPCThreadState::self()->flushCommands();
18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear()
18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
18662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // here, the window manager tells us explicitly that we should destroy
18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // the surface's resource. Soon after this call, it will also release
18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // its last reference (which will call the dtor); however, it is possible
18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // that a client living in the same process still holds references which
19062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // would delay the call to the dtor -- that is why we need this explicit
19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // "clear()" call.
19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) {
19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setLayer(mToken, layer);
20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) {
20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
20462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setPosition(mToken, x, y);
20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setSize(mToken, w, h);
21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
21662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() {
21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->hide(mToken);
22262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) {
22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->show(mToken, layer);
22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() {
23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->freeze(mToken);
23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() {
23862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
23962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
24062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
24162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
24262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->unfreeze(mToken);
24362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
24462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
24562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
24662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
24762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
24862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
24962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFlags(mToken, flags, mask);
25062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
25162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
25262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
25362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
25462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
25562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
25662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setTransparentRegionHint(mToken, transparent);
25762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
25862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) {
25962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
26062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
26162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
26262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
26362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setAlpha(mToken, alpha);
26462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
26562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
26662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
26762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
26862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
26962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
27062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
27162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
27262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) {
27362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
27462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (client == 0) return INVALID_OPERATION;
27562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
27662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
27762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFreezeTint(mToken, tint);
27862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
27962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
28062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopiansp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel)
28162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
28262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    sp<SurfaceComposerClient> client;
28362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    ISurfaceFlingerClient::surface_data_t data;
28462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    sp<IBinder> clientBinder= parcel->readStrongBinder();
28562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
28662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    data.token              = parcel->readInt32();
28762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    data.identity           = parcel->readInt32();
28862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    PixelFormat format      = parcel->readInt32();
28962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    uint32_t flags          = parcel->readInt32();
29062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
29162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (clientBinder != NULL)
29262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        client = SurfaceComposerClient::clientForConnection(clientBinder);
29362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
29462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return new SurfaceControl(client, surface, data, 0, 0, format, flags, false);
29562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
29662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
29762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::writeToParcel(const sp<SurfaceControl>& surface, Parcel* parcel)
29862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
29962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    uint32_t flags=0;
30062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    uint32_t format=0;
30162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    SurfaceID token = -1;
30262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    uint32_t identity = 0;
30362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    sp<SurfaceComposerClient> client;
30462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    sp<ISurface> sur;
30562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (SurfaceControl::isValid(surface)) {
30662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        token = surface->mToken;
30762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        identity = surface->mIdentity;
30862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        client = surface->mClient;
30962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        sur = surface->mSurface;
31062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        format = surface->mFormat;
31162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        flags = surface->mFlags;
31262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
31362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
31462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
31562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeInt32(token);
31662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeInt32(identity);
31762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeInt32(format);
31862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    parcel->writeInt32(flags);
31962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return NO_ERROR;
32062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
32162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
32262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianbool SurfaceControl::isSameSurface(
32362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
32462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
32562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (lhs == 0 || rhs == 0)
32662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return false;
32762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
32862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
32962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
33062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
33162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::validate(per_client_cblk_t const* cblk) const
33262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
33362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mToken<0 || mClient==0) {
33462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
33562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, mClient.get());
33662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
33762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
33862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (cblk == 0) {
33962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
34062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
34162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
34262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = cblk->validate(mToken);
34362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err != NO_ERROR) {
34462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
34562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, err, strerror(-err));
34662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return err;
34762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
34862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
34962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("using an invalid surface id=%d, identity=%u should be %d",
35062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, cblk->layers[mToken].identity);
35162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
35262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
35362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return NO_ERROR;
35462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
35562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
356076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
357076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian//  Surface
358076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurface::Surface(const sp<SurfaceComposerClient>& client,
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurface>& surface,
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const ISurfaceFlingerClient::surface_data_t& data,
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bool owner)
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mClient(client), mSurface(surface),
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mToken(data.token), mIdentity(data.identity),
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      mFormat(format), mFlags(flags), mOwner(owner)
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
36962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurfaceControl = new SurfaceControl(
37062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian            client, surface, data, w, h, format, flags, owner);
37162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::connect          = connect;
373076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::disconnect       = disconnect;
374076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::setSwapInterval  = setSwapInterval;
375076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::setSwapRectangle = setSwapRectangle;
376076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::dequeueBuffer    = dequeueBuffer;
377076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::lockBuffer       = lockBuffer;
378076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::queueBuffer      = queueBuffer;
379076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle.makeInvalid();
381076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
382076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    DisplayInfo dinfo;
383076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
384076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
385076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
386076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: set real values here
387076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
388076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
389076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface()
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
39440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // this is a client-side operation, the surface is destroyed, unmap
39540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // its buffers in this process.
39640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    for (int i=0 ; i<2 ; i++) {
39740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        if (mBuffers[i] != 0) {
39840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian            BufferMapper::get().unmap(mBuffers[i]->getHandle(), this);
39940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        }
40040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
40140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
40240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    destroy();
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopianvoid Surface::destroy()
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
40762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurfaceControl->destroy();
40840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
40940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // clear all references and trigger an IPC now, to make sure things
41040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // happen without delay, since these resources are quite heavy.
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mClient.clear();
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurface.clear();
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->flushCommands();
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopianvoid Surface::clear()
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
41862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurfaceControl->clear();
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::validate(per_client_cblk_t const* cblk) const
422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
42340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (mToken<0 || mClient==0) {
42440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
42540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian                mToken, mIdentity, mClient.get());
42640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return NO_INIT;
42740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
428076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (cblk == 0) {
429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
430076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
431076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
432076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = cblk->validate(mToken);
433076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR) {
434076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
435076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                mToken, mIdentity, err, strerror(-err));
436076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
437076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
438076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("using an invalid surface id=%d, identity=%u should be %d",
440076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                mToken, mIdentity, cblk->layers[mToken].identity);
441076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
445076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
447076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::setSwapRectangle(android_native_window_t* window,
449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        int l, int t, int w, int h)
450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    self->setSwapRectangle(Rect(l, t, l+w, t+h));
453076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
454076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::connect(android_native_window_t* window)
457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
459076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
460076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::disconnect(android_native_window_t* window)
461076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
462076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
463076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval)
465076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
466076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
467076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
468076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
469076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window,
470076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        android_native_buffer_t** buffer)
471076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->dequeueBuffer(buffer);
474076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window,
477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        android_native_buffer_t* buffer)
478076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
479076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
480076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->lockBuffer(buffer);
481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
482076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
483076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window,
484076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        android_native_buffer_t* buffer)
485076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
486076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->queueBuffer(buffer);
488076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
491076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer)
493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: dequeueBuffer() needs proper implementation
495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
497076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
498076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    per_client_cblk_t* const cblk = mClient->mControl;
499076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = validate(cblk);
500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
503076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceID index(mToken);
504076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
505076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int32_t backIdx = cblk->lock_layer(size_t(index),
506076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            per_client_cblk_t::BLOCKING);
507076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
508076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (backIdx < 0)
509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return status_t(backIdx);
510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
511076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mBackbufferIndex = backIdx;
512076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    layer_cblk_t* const lcblk = &(cblk->layers[index]);
513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
514076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    volatile const surface_info_t* const back = lcblk->surface + backIdx;
515076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (back->flags & surface_info_t::eNeedNewBuffer) {
516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        getBufferLocked(backIdx);
517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
518076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
519076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
520076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    *buffer = backBuffer.get();
521076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
522076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
523076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
525076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer)
526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
52740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
52840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
52940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    per_client_cblk_t* const cblk = mClient->mControl;
53040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    status_t err = validate(cblk);
53140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (err != NO_ERROR)
53240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return err;
53340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
534076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: lockBuffer() needs proper implementation
535076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer)
539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
540076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
541076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
542076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    per_client_cblk_t* const cblk = mClient->mControl;
543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = validate(cblk);
544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // transmit the dirty region
548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const Region dirty(swapRectangle());
549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceID index(mToken);
550076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    layer_cblk_t* const lcblk = &(cblk->layers[index]);
551076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    _send_dirty_region(lcblk, dirty);
552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
553076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
554076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (!(newstate & eNextFlipPending))
555076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mClient->signalServer();
556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
557076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
560076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) {
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return Surface::lock(info, NULL, blocking);
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking)
567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: needs some locking here
569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_buffer_t* backBuffer;
570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = dequeueBuffer(&backBuffer);
571076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == NO_ERROR) {
572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        err = lockBuffer(backBuffer);
573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            backBuffer->common.incRef(&backBuffer->common);
575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            mLockedBuffer = backBuffer;
576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->w      = backBuffer->width;
577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->h      = backBuffer->height;
578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->s      = backBuffer->stride;
579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->usage  = backBuffer->usage;
580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->format = backBuffer->format;
581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            other->bits   = backBuffer->bits;
582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // we handle copy-back here...
584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const Rect bounds(backBuffer->width, backBuffer->height);
586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            Region newDirtyRegion;
587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            per_client_cblk_t* const cblk = mClient->mControl;
589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]);
590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex;
591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (back->flags & surface_info_t::eBufferDirty) {
592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                // content is meaningless in this case and the whole surface
593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                // needs to be redrawn.
594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                newDirtyRegion.set(bounds);
595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                if (dirty) {
596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    *dirty = newDirtyRegion;
597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            } else
599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            {
600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                if (dirty) {
601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    dirty->andSelf(Region(bounds));
602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    newDirtyRegion = *dirty;
603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                } else {
604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    newDirtyRegion.set(bounds);
605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
606076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                Region copyback;
607076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                if (!(lcblk->flags & eNoCopyBack)) {
608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    const Region previousDirtyRegion(dirtyRegion());
609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    copyback = previousDirtyRegion.subtract(newDirtyRegion);
610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
612076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                if (!copyback.isEmpty() && frontBuffer!=0) {
613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    // copy front to back
614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    copyBlt(backBuffer, frontBuffer.get(), copyback);
615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
617076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            setDirtyRegion(newDirtyRegion);
618076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            Rect lockBounds(backBuffer->width, backBuffer->height);
621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            if (dirty) {
622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                lockBounds = dirty->bounds();
623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            buffer_handle_t handle;
625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            backBuffer->getHandle(backBuffer, &handle);
626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            status_t res = BufferMapper::get().lock(handle,
627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    lockBounds);
629076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            LOGW_IF(res, "failed locking buffer %d (%p)",
630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                    mBackbufferIndex, handle);
631076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            setSwapRectangle(lockBounds);
632076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
634076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
636076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost()
638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: needs some locking here
640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
641076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (mLockedBuffer == 0)
642076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return BAD_VALUE;
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
644076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    buffer_handle_t handle;
645076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer->getHandle(mLockedBuffer, &handle);
646076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t res = BufferMapper::get().unlock(handle);
647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(res, "failed unlocking buffer %d (%p)",
648076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            mBackbufferIndex, handle);
649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
650076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const Rect dirty(dirtyRegion().bounds());
651076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    setSwapRectangle(dirty);
652076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = queueBuffer(mLockedBuffer);
653076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer->common.decRef(&mLockedBuffer->common);
654076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer = 0;
655076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
658076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::_send_dirty_region(
659076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer_cblk_t* lcblk, const Region& dirty)
660076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
661076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
662076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    flat_region_t* flat_region = lcblk->region + index;
663076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
664076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err < NO_ERROR) {
665076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // region doesn't fit, use the bounds
666076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const Region reg(dirty.bounds());
667076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        reg.write(flat_region, sizeof(flat_region_t));
668076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion Surface::dirtyRegion() const  {
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mDirtyRegion;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setDirtyRegion(const Region& region) const {
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion = region;
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Rect& Surface::swapRectangle() const {
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mSwapRectangle;
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) {
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle = r;
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<Surface> Surface::readFromParcel(Parcel* parcel)
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<SurfaceComposerClient> client;
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ISurfaceFlingerClient::surface_data_t data;
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<IBinder> clientBinder= parcel->readStrongBinder();
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    data.token              = parcel->readInt32();
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    data.identity           = parcel->readInt32();
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormat format      = parcel->readInt32();
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags          = parcel->readInt32();
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (clientBinder != NULL)
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        client = SurfaceComposerClient::clientForConnection(clientBinder);
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new Surface(client, surface, data, 0, 0, format, flags, false);
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags=0;
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t format=0;
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SurfaceID token = -1;
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t identity = 0;
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<SurfaceComposerClient> client;
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<ISurface> sur;
70940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (Surface::isValid(surface)) {
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        token = surface->mToken;
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        identity = surface->mIdentity;
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        client = surface->mClient;
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sur = surface->mSurface;
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = surface->mFormat;
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        flags = surface->mFlags;
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeInt32(token);
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeInt32(identity);
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeInt32(format);
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    parcel->writeInt32(flags);
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs)
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (lhs == 0 || rhs == 0)
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::getBufferLocked(int index)
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = NO_MEMORY;
736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<SurfaceBuffer> buffer = mSurface->getBuffer();
737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (buffer != 0) {
739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (currentBuffer != 0) {
7414243e666213029a293935987c979831093fb0779Mathias Agopian            BufferMapper::get().unmap(currentBuffer->getHandle(), this);
742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            currentBuffer.clear();
743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
7444243e666213029a293935987c979831093fb0779Mathias Agopian        err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this);
745076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
747076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            currentBuffer = buffer;
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
75462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
75562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setLayer(int32_t layer) {
75662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setLayer(layer);
75762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
75862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setPosition(int32_t x, int32_t y) {
75962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setPosition(x, y);
76062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
76162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setSize(uint32_t w, uint32_t h) {
76262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setSize(w, h);
76362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
76462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::hide() {
76562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->hide();
76662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
76762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::show(int32_t layer) {
76862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->show(layer);
76962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
77062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::freeze() {
77162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->freeze();
77262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
77362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::unfreeze() {
77462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->unfreeze();
77562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
77662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setFlags(uint32_t flags, uint32_t mask) {
77762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setFlags(flags, mask);
77862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
77962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setTransparentRegionHint(const Region& transparent) {
78062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setTransparentRegionHint(transparent);
78162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
78262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setAlpha(float alpha) {
78362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setAlpha(alpha);
78462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
78562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
78662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setMatrix(dsdx, dtdx, dsdy, dtdy);
78762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
78862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setFreezeTint(uint32_t tint) {
78962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return mSurfaceControl->setFreezeTint(tint);
79062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
79162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
79262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
795