GraphicBuffer.cpp revision 18fae75350bcd5f19ef90afb533e3fbedfd4c83b
13330b203039dea366d4981db1408a460134b2d2cMathias Agopian/*
23330b203039dea366d4981db1408a460134b2d2cMathias Agopian * Copyright (C) 2007 The Android Open Source Project
33330b203039dea366d4981db1408a460134b2d2cMathias Agopian *
43330b203039dea366d4981db1408a460134b2d2cMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
53330b203039dea366d4981db1408a460134b2d2cMathias Agopian * you may not use this file except in compliance with the License.
63330b203039dea366d4981db1408a460134b2d2cMathias Agopian * You may obtain a copy of the License at
73330b203039dea366d4981db1408a460134b2d2cMathias Agopian *
83330b203039dea366d4981db1408a460134b2d2cMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
93330b203039dea366d4981db1408a460134b2d2cMathias Agopian *
103330b203039dea366d4981db1408a460134b2d2cMathias Agopian * Unless required by applicable law or agreed to in writing, software
113330b203039dea366d4981db1408a460134b2d2cMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
123330b203039dea366d4981db1408a460134b2d2cMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133330b203039dea366d4981db1408a460134b2d2cMathias Agopian * See the License for the specific language governing permissions and
143330b203039dea366d4981db1408a460134b2d2cMathias Agopian * limitations under the License.
153330b203039dea366d4981db1408a460134b2d2cMathias Agopian */
163330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian#define LOG_TAG "GraphicBuffer"
1898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
193330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <stdlib.h>
203330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <stdint.h>
213330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <sys/types.h>
223330b203039dea366d4981db1408a460134b2d2cMathias Agopian
233330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <utils/Errors.h>
243330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <utils/Log.h>
253330b203039dea366d4981db1408a460134b2d2cMathias Agopian
263330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
273330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferAllocator.h>
283330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferMapper.h>
293330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/PixelFormat.h>
303330b203039dea366d4981db1408a460134b2d2cMathias Agopian
313330b203039dea366d4981db1408a460134b2d2cMathias Agopiannamespace android {
323330b203039dea366d4981db1408a460134b2d2cMathias Agopian
333330b203039dea366d4981db1408a460134b2d2cMathias Agopian// ===========================================================================
34697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev// Buffer and implementation of ANativeWindowBuffer
353330b203039dea366d4981db1408a460134b2d2cMathias Agopian// ===========================================================================
363330b203039dea366d4981db1408a460134b2d2cMathias Agopian
37b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stozastatic uint64_t getUniqueId() {
38b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    static volatile int32_t nextId = 0;
39b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    uint64_t id = static_cast<uint64_t>(getpid()) << 32;
40b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    id |= static_cast<uint32_t>(android_atomic_inc(&nextId));
41b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    return id;
42b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza}
43b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza
443330b203039dea366d4981db1408a460134b2d2cMathias AgopianGraphicBuffer::GraphicBuffer()
4554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
46b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza      mInitCheck(NO_ERROR), mId(getUniqueId())
47b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza{
483330b203039dea366d4981db1408a460134b2d2cMathias Agopian    width  =
493330b203039dea366d4981db1408a460134b2d2cMathias Agopian    height =
503330b203039dea366d4981db1408a460134b2d2cMathias Agopian    stride =
513330b203039dea366d4981db1408a460134b2d2cMathias Agopian    format =
523330b203039dea366d4981db1408a460134b2d2cMathias Agopian    usage  = 0;
533330b203039dea366d4981db1408a460134b2d2cMathias Agopian    handle = NULL;
543330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
553330b203039dea366d4981db1408a460134b2d2cMathias Agopian
563330b203039dea366d4981db1408a460134b2d2cMathias AgopianGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
573330b203039dea366d4981db1408a460134b2d2cMathias Agopian        PixelFormat reqFormat, uint32_t reqUsage)
5854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
59b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza      mInitCheck(NO_ERROR), mId(getUniqueId())
603330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
613330b203039dea366d4981db1408a460134b2d2cMathias Agopian    width  =
623330b203039dea366d4981db1408a460134b2d2cMathias Agopian    height =
633330b203039dea366d4981db1408a460134b2d2cMathias Agopian    stride =
643330b203039dea366d4981db1408a460134b2d2cMathias Agopian    format =
653330b203039dea366d4981db1408a460134b2d2cMathias Agopian    usage  = 0;
663330b203039dea366d4981db1408a460134b2d2cMathias Agopian    handle = NULL;
673330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mInitCheck = initSize(w, h, reqFormat, reqUsage);
683330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
693330b203039dea366d4981db1408a460134b2d2cMathias Agopian
7054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias AgopianGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
7154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        PixelFormat inFormat, uint32_t inUsage,
7254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
7354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
7454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian      mBufferMapper(GraphicBufferMapper::get()),
75b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza      mInitCheck(NO_ERROR), mId(getUniqueId())
7654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian{
7754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    width  = w;
7854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    height = h;
7954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    stride = inStride;
8054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    format = inFormat;
8154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    usage  = inUsage;
8254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    handle = inHandle;
8354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian}
8454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
85697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan MalchevGraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
86309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
87309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis      mBufferMapper(GraphicBufferMapper::get()),
88b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza      mInitCheck(NO_ERROR), mWrappedBuffer(buffer), mId(getUniqueId())
89309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis{
90309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    width  = buffer->width;
91309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    height = buffer->height;
92309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    stride = buffer->stride;
93309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    format = buffer->format;
94309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    usage  = buffer->usage;
95309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    handle = buffer->handle;
96309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis}
97309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis
9898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias AgopianGraphicBuffer::~GraphicBuffer()
993330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
10098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (handle) {
10198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        free_handle();
1023330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
1033330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1043330b203039dea366d4981db1408a460134b2d2cMathias Agopian
10598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopianvoid GraphicBuffer::free_handle()
1063330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
10798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (mOwner == ownHandle) {
108309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis        mBufferMapper.unregisterBuffer(handle);
10998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        native_handle_close(handle);
11098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        native_handle_delete(const_cast<native_handle*>(handle));
11198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    } else if (mOwner == ownData) {
11298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
11398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        allocator.free(handle);
1143330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
115309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    mWrappedBuffer = 0;
1163330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1173330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1183330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::initCheck() const {
1193330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return mInitCheck;
1203330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1213330b203039dea366d4981db1408a460134b2d2cMathias Agopian
122678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopianvoid GraphicBuffer::dumpAllocationsToSystemLog()
123678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian{
124678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian    GraphicBufferAllocator::dumpToSystemLog();
125678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian}
126678bdd6349344df254cc0c3377a40fd99e216635Mathias Agopian
127697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan MalchevANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
1283330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
12918fae75350bcd5f19ef90afb533e3fbedfd4c83bColin Cross    LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer");
130697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    return static_cast<ANativeWindowBuffer*>(
1313330b203039dea366d4981db1408a460134b2d2cMathias Agopian            const_cast<GraphicBuffer*>(this));
1323330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1333330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1343330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
1353330b203039dea366d4981db1408a460134b2d2cMathias Agopian        uint32_t reqUsage)
1363330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
13754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian    if (mOwner != ownData)
13854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian        return INVALID_OPERATION;
13954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian
140579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian    if (handle && w==width && h==height && f==format && reqUsage==usage)
141579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian        return NO_ERROR;
142579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1433330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (handle) {
1443330b203039dea366d4981db1408a460134b2d2cMathias Agopian        GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
1453330b203039dea366d4981db1408a460134b2d2cMathias Agopian        allocator.free(handle);
1463330b203039dea366d4981db1408a460134b2d2cMathias Agopian        handle = 0;
1473330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
1483330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return initSize(w, h, f, reqUsage);
1493330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1503330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1513330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
1523330b203039dea366d4981db1408a460134b2d2cMathias Agopian        uint32_t reqUsage)
1533330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
1543330b203039dea366d4981db1408a460134b2d2cMathias Agopian    GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
1553330b203039dea366d4981db1408a460134b2d2cMathias Agopian    status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
1563330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (err == NO_ERROR) {
1573330b203039dea366d4981db1408a460134b2d2cMathias Agopian        this->width  = w;
1583330b203039dea366d4981db1408a460134b2d2cMathias Agopian        this->height = h;
1593330b203039dea366d4981db1408a460134b2d2cMathias Agopian        this->format = format;
1603330b203039dea366d4981db1408a460134b2d2cMathias Agopian        this->usage  = reqUsage;
1613330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
1623330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return err;
1633330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1643330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1653330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::lock(uint32_t usage, void** vaddr)
1663330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
1673330b203039dea366d4981db1408a460134b2d2cMathias Agopian    const Rect lockBounds(width, height);
1683330b203039dea366d4981db1408a460134b2d2cMathias Agopian    status_t res = lock(usage, lockBounds, vaddr);
1693330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return res;
1703330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1713330b203039dea366d4981db1408a460134b2d2cMathias Agopian
1723330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
1733330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
1743330b203039dea366d4981db1408a460134b2d2cMathias Agopian    if (rect.left < 0 || rect.right  > this->width ||
1753330b203039dea366d4981db1408a460134b2d2cMathias Agopian        rect.top  < 0 || rect.bottom > this->height) {
176e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
1773330b203039dea366d4981db1408a460134b2d2cMathias Agopian                rect.left, rect.top, rect.right, rect.bottom,
1783330b203039dea366d4981db1408a460134b2d2cMathias Agopian                this->width, this->height);
1793330b203039dea366d4981db1408a460134b2d2cMathias Agopian        return BAD_VALUE;
1803330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
1813330b203039dea366d4981db1408a460134b2d2cMathias Agopian    status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
1823330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return res;
1833330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
1843330b203039dea366d4981db1408a460134b2d2cMathias Agopian
185c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvalastatus_t GraphicBuffer::lockYCbCr(uint32_t usage, android_ycbcr *ycbcr)
186c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala{
187c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    const Rect lockBounds(width, height);
188c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    status_t res = lockYCbCr(usage, lockBounds, ycbcr);
189c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    return res;
190c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala}
191c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
192c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvalastatus_t GraphicBuffer::lockYCbCr(uint32_t usage, const Rect& rect,
193c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        android_ycbcr *ycbcr)
194c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala{
195c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    if (rect.left < 0 || rect.right  > this->width ||
196c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        rect.top  < 0 || rect.bottom > this->height) {
197c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
198c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala                rect.left, rect.top, rect.right, rect.bottom,
199c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala                this->width, this->height);
200c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala        return BAD_VALUE;
201c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    }
202c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    status_t res = getBufferMapper().lockYCbCr(handle, usage, rect, ycbcr);
203c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala    return res;
204c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala}
205c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
2063330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBuffer::unlock()
2073330b203039dea366d4981db1408a460134b2d2cMathias Agopian{
2083330b203039dea366d4981db1408a460134b2d2cMathias Agopian    status_t res = getBufferMapper().unlock(handle);
2093330b203039dea366d4981db1408a460134b2d2cMathias Agopian    return res;
2103330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
2113330b203039dea366d4981db1408a460134b2d2cMathias Agopian
2128f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBuffer::lockAsync(uint32_t usage, void** vaddr, int fenceFd)
2138f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
2148f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    const Rect lockBounds(width, height);
2158f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    status_t res = lockAsync(usage, lockBounds, vaddr, fenceFd);
2168f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    return res;
2178f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
2188f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
2198f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBuffer::lockAsync(uint32_t usage, const Rect& rect, void** vaddr, int fenceFd)
2208f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
2218f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    if (rect.left < 0 || rect.right  > this->width ||
2228f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        rect.top  < 0 || rect.bottom > this->height) {
2238f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
2248f3960179c56767e5077be8337792bd4e244b7d7Francis Hart                rect.left, rect.top, rect.right, rect.bottom,
2258f3960179c56767e5077be8337792bd4e244b7d7Francis Hart                this->width, this->height);
2268f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        return BAD_VALUE;
2278f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    }
2288f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    status_t res = getBufferMapper().lockAsync(handle, usage, rect, vaddr, fenceFd);
2298f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    return res;
2308f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
2318f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
2328f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBuffer::lockAsyncYCbCr(uint32_t usage, android_ycbcr *ycbcr, int fenceFd)
2338f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
2348f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    const Rect lockBounds(width, height);
2358f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    status_t res = lockAsyncYCbCr(usage, lockBounds, ycbcr, fenceFd);
2368f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    return res;
2378f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
2388f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
2398f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBuffer::lockAsyncYCbCr(uint32_t usage, const Rect& rect, android_ycbcr *ycbcr, int fenceFd)
2408f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
2418f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    if (rect.left < 0 || rect.right  > this->width ||
2428f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        rect.top  < 0 || rect.bottom > this->height) {
2438f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
2448f3960179c56767e5077be8337792bd4e244b7d7Francis Hart                rect.left, rect.top, rect.right, rect.bottom,
2458f3960179c56767e5077be8337792bd4e244b7d7Francis Hart                this->width, this->height);
2468f3960179c56767e5077be8337792bd4e244b7d7Francis Hart        return BAD_VALUE;
2478f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    }
2488f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    status_t res = getBufferMapper().lockAsyncYCbCr(handle, usage, rect, ycbcr, fenceFd);
2498f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    return res;
2508f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
2518f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
2528f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBuffer::unlockAsync(int *fenceFd)
2538f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
2548f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    status_t res = getBufferMapper().unlockAsync(handle, fenceFd);
2558f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    return res;
2568f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
2578f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
25898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopiansize_t GraphicBuffer::getFlattenedSize() const {
259b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    return (10 + (handle ? handle->numInts : 0))*sizeof(int);
26098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian}
26198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
26298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopiansize_t GraphicBuffer::getFdCount() const {
26398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    return handle ? handle->numFds : 0;
26498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian}
2653330b203039dea366d4981db1408a460134b2d2cMathias Agopian
266e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
26798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
26898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (size < sizeNeeded) return NO_MEMORY;
26998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
27098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    size_t fdCountNeeded = GraphicBuffer::getFdCount();
27198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (count < fdCountNeeded) return NO_MEMORY;
27298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
273b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    int32_t* buf = static_cast<int32_t*>(buffer);
27498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[0] = 'GBFR';
27598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[1] = width;
27698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[2] = height;
27798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[3] = stride;
27898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[4] = format;
27998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    buf[5] = usage;
280b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    buf[6] = static_cast<int32_t>(mId >> 32);
281b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    buf[7] = static_cast<int32_t>(mId & 0xFFFFFFFFull);
282b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    buf[8] = 0;
283b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    buf[9] = 0;
2843330b203039dea366d4981db1408a460134b2d2cMathias Agopian
28598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (handle) {
286b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza        buf[8] = handle->numFds;
287b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza        buf[9] = handle->numInts;
28898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        native_handle_t const* const h = handle;
28998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        memcpy(fds,     h->data,             h->numFds*sizeof(int));
290b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza        memcpy(&buf[10], h->data + h->numFds, h->numInts*sizeof(int));
29198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    }
29298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
293e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
294e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    size -= sizeNeeded;
295bc96e4714f4cc1ae598f122b3b9f7998c09fe674Andy McFadden    if (handle) {
296bc96e4714f4cc1ae598f122b3b9f7998c09fe674Andy McFadden        fds += handle->numFds;
297bc96e4714f4cc1ae598f122b3b9f7998c09fe674Andy McFadden        count -= handle->numFds;
298bc96e4714f4cc1ae598f122b3b9f7998c09fe674Andy McFadden    }
299e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
30098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    return NO_ERROR;
30198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian}
30298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
303e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t GraphicBuffer::unflatten(
304e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
30598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (size < 8*sizeof(int)) return NO_MEMORY;
30698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
30798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    int const* buf = static_cast<int const*>(buffer);
30898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (buf[0] != 'GBFR') return BAD_TYPE;
30998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
310b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    const size_t numFds  = buf[8];
311b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    const size_t numInts = buf[9];
3123330b203039dea366d4981db1408a460134b2d2cMathias Agopian
313b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    const size_t sizeNeeded = (10 + numInts) * sizeof(int);
31498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (size < sizeNeeded) return NO_MEMORY;
31598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
31698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    size_t fdCountNeeded = 0;
31798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (count < fdCountNeeded) return NO_MEMORY;
31898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
31998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (handle) {
32098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        // free previous handle if any
32198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        free_handle();
32298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    }
32398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
32498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    if (numFds || numInts) {
32598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        width  = buf[1];
32698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        height = buf[2];
32798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        stride = buf[3];
32898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        format = buf[4];
32998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        usage  = buf[5];
33098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        native_handle* h = native_handle_create(numFds, numInts);
33198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        memcpy(h->data,          fds,     numFds*sizeof(int));
332b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza        memcpy(h->data + numFds, &buf[10], numInts*sizeof(int));
33398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        handle = h;
3343330b203039dea366d4981db1408a460134b2d2cMathias Agopian    } else {
33598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        width = height = stride = format = usage = 0;
33698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian        handle = NULL;
3373330b203039dea366d4981db1408a460134b2d2cMathias Agopian    }
33898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian
339b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    mId = static_cast<uint64_t>(buf[6]) << 32;
340b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza    mId |= static_cast<uint32_t>(buf[7]);
341b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza
34298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    mOwner = ownHandle;
343309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis
344309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    if (handle != 0) {
345d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        status_t err = mBufferMapper.registerBuffer(handle);
346d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        if (err != NO_ERROR) {
3472aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu            width = height = stride = format = usage = 0;
3482aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu            handle = NULL;
349d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis            ALOGE("unflatten: registerBuffer failed: %s (%d)",
350d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis                    strerror(-err), err);
351d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis            return err;
352d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        }
353309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis    }
354309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis
355e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
356e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    size -= sizeNeeded;
357e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    fds += numFds;
358e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    count -= numFds;
359e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
36098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian    return NO_ERROR;
3613330b203039dea366d4981db1408a460134b2d2cMathias Agopian}
3623330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian// ---------------------------------------------------------------------------
3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian
3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian}; // namespace android
366