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 313796aaf7fb160fea12bddc8406d7f006ce811eb43Michael Lentine // Limit the maxNumber to be relatively small. The number of fds or ints 314796aaf7fb160fea12bddc8406d7f006ce811eb43Michael Lentine // should not come close to this number, and the number itself was simply 315796aaf7fb160fea12bddc8406d7f006ce811eb43Michael Lentine // chosen to be high enough to not cause issues and low enough to prevent 316796aaf7fb160fea12bddc8406d7f006ce811eb43Michael Lentine // overflow problems. 317796aaf7fb160fea12bddc8406d7f006ce811eb43Michael Lentine const size_t maxNumber = 4096; 318dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine if (numFds >= maxNumber || numInts >= (maxNumber - 10)) { 319dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine width = height = stride = format = usage = 0; 320dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine handle = NULL; 321dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine ALOGE("unflatten: numFds or numInts is too large: %d, %d", 322dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine numFds, numInts); 323dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine return BAD_VALUE; 324dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine } 325dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine 326b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza const size_t sizeNeeded = (10 + numInts) * sizeof(int); 32798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian if (size < sizeNeeded) return NO_MEMORY; 32898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian 329dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine size_t fdCountNeeded = numFds; 33098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian if (count < fdCountNeeded) return NO_MEMORY; 33198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian 33298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian if (handle) { 33398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian // free previous handle if any 33498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian free_handle(); 33598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian } 33698e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian 33798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian if (numFds || numInts) { 33898e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian width = buf[1]; 33998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian height = buf[2]; 34098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian stride = buf[3]; 34198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian format = buf[4]; 34298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian usage = buf[5]; 34398e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian native_handle* h = native_handle_create(numFds, numInts); 344dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine if (!h) { 345dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine width = height = stride = format = usage = 0; 346dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine handle = NULL; 347dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine ALOGE("unflatten: native_handle_create failed"); 348dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine return NO_MEMORY; 349dfd06b89a4b77fc75eb85a3c1c700da3621c0118Michael Lentine } 35098e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian memcpy(h->data, fds, numFds*sizeof(int)); 351b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza memcpy(h->data + numFds, &buf[10], numInts*sizeof(int)); 35298e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian handle = h; 3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 35498e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian width = height = stride = format = usage = 0; 35598e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian handle = NULL; 3563330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 35798e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian 358b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza mId = static_cast<uint64_t>(buf[6]) << 32; 359b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza mId |= static_cast<uint32_t>(buf[7]); 360b1363d37fc6a661508fad106eb7698c5850a6c17Dan Stoza 36198e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian mOwner = ownHandle; 362309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis 363309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis if (handle != 0) { 364d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis status_t err = mBufferMapper.registerBuffer(handle); 365d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis if (err != NO_ERROR) { 3662aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu width = height = stride = format = usage = 0; 3672aff7025482cc40d2ebd45f81cdb318ac1c6f868Lingyun Zhu handle = NULL; 368d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ALOGE("unflatten: registerBuffer failed: %s (%d)", 369d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis strerror(-err), err); 370d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis return err; 371d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis } 372309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis } 373309d3bb2f902163356f9d40b6d45c11b435d77a9Jamie Gennis 374e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded); 375e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian size -= sizeNeeded; 376e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian fds += numFds; 377e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count -= numFds; 378e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 37998e71ddaede9a0bfb681fd237bec1f66c6c53193Mathias Agopian return NO_ERROR; 3803330b203039dea366d4981db1408a460134b2d2cMathias Agopian} 3813330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3823330b203039dea366d4981db1408a460134b2d2cMathias Agopian// --------------------------------------------------------------------------- 3833330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3843330b203039dea366d4981db1408a460134b2d2cMathias Agopian}; // namespace android 385