GraphicBuffer.cpp revision 9042b4564de5477b18e680c7dce13b587a681dd9
16950e428feaccc8164b989ef64e771a99948797aMathias Agopian/* 26950e428feaccc8164b989ef64e771a99948797aMathias Agopian * Copyright (C) 2007 The Android Open Source Project 36950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 46950e428feaccc8164b989ef64e771a99948797aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 56950e428feaccc8164b989ef64e771a99948797aMathias Agopian * you may not use this file except in compliance with the License. 66950e428feaccc8164b989ef64e771a99948797aMathias Agopian * You may obtain a copy of the License at 76950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 86950e428feaccc8164b989ef64e771a99948797aMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 96950e428feaccc8164b989ef64e771a99948797aMathias Agopian * 106950e428feaccc8164b989ef64e771a99948797aMathias Agopian * Unless required by applicable law or agreed to in writing, software 116950e428feaccc8164b989ef64e771a99948797aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 126950e428feaccc8164b989ef64e771a99948797aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136950e428feaccc8164b989ef64e771a99948797aMathias Agopian * See the License for the specific language governing permissions and 146950e428feaccc8164b989ef64e771a99948797aMathias Agopian * limitations under the License. 156950e428feaccc8164b989ef64e771a99948797aMathias Agopian */ 166950e428feaccc8164b989ef64e771a99948797aMathias Agopian 176950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <stdlib.h> 186950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <stdint.h> 196950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <sys/types.h> 206950e428feaccc8164b989ef64e771a99948797aMathias Agopian 216950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <binder/Parcel.h> 226950e428feaccc8164b989ef64e771a99948797aMathias Agopian 236950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <utils/Errors.h> 246950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <utils/Log.h> 256950e428feaccc8164b989ef64e771a99948797aMathias Agopian 266950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <ui/GraphicBuffer.h> 276950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <ui/GraphicBufferAllocator.h> 286950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <ui/GraphicBufferMapper.h> 296950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <ui/PixelFormat.h> 306950e428feaccc8164b989ef64e771a99948797aMathias Agopian 316950e428feaccc8164b989ef64e771a99948797aMathias Agopian#include <pixelflinger/pixelflinger.h> 326950e428feaccc8164b989ef64e771a99948797aMathias Agopian 336950e428feaccc8164b989ef64e771a99948797aMathias Agopiannamespace android { 346950e428feaccc8164b989ef64e771a99948797aMathias Agopian 356950e428feaccc8164b989ef64e771a99948797aMathias Agopian// =========================================================================== 366950e428feaccc8164b989ef64e771a99948797aMathias Agopian// Buffer and implementation of android_native_buffer_t 376950e428feaccc8164b989ef64e771a99948797aMathias Agopian// =========================================================================== 386950e428feaccc8164b989ef64e771a99948797aMathias Agopian 396950e428feaccc8164b989ef64e771a99948797aMathias AgopianGraphicBuffer::GraphicBuffer() 409042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 416950e428feaccc8164b989ef64e771a99948797aMathias Agopian mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 426950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 436950e428feaccc8164b989ef64e771a99948797aMathias Agopian width = 446950e428feaccc8164b989ef64e771a99948797aMathias Agopian height = 456950e428feaccc8164b989ef64e771a99948797aMathias Agopian stride = 466950e428feaccc8164b989ef64e771a99948797aMathias Agopian format = 476950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = 0; 486950e428feaccc8164b989ef64e771a99948797aMathias Agopian handle = NULL; 496950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 506950e428feaccc8164b989ef64e771a99948797aMathias Agopian 516950e428feaccc8164b989ef64e771a99948797aMathias AgopianGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 526950e428feaccc8164b989ef64e771a99948797aMathias Agopian PixelFormat reqFormat, uint32_t reqUsage) 539042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 546950e428feaccc8164b989ef64e771a99948797aMathias Agopian mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 556950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 566950e428feaccc8164b989ef64e771a99948797aMathias Agopian width = 576950e428feaccc8164b989ef64e771a99948797aMathias Agopian height = 586950e428feaccc8164b989ef64e771a99948797aMathias Agopian stride = 596950e428feaccc8164b989ef64e771a99948797aMathias Agopian format = 606950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = 0; 616950e428feaccc8164b989ef64e771a99948797aMathias Agopian handle = NULL; 626950e428feaccc8164b989ef64e771a99948797aMathias Agopian mInitCheck = initSize(w, h, reqFormat, reqUsage); 636950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 646950e428feaccc8164b989ef64e771a99948797aMathias Agopian 659042b4564de5477b18e680c7dce13b587a681dd9Mathias AgopianGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 669042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian PixelFormat inFormat, uint32_t inUsage, 679042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) 689042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), 699042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian mBufferMapper(GraphicBufferMapper::get()), 709042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 719042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian{ 729042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian width = w; 739042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian height = h; 749042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian stride = inStride; 759042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian format = inFormat; 769042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian usage = inUsage; 779042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian handle = inHandle; 789042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian} 799042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian 806950e428feaccc8164b989ef64e771a99948797aMathias AgopianGraphicBuffer::GraphicBuffer(const Parcel& data) 819042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian : BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()), 826950e428feaccc8164b989ef64e771a99948797aMathias Agopian mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 836950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 846950e428feaccc8164b989ef64e771a99948797aMathias Agopian // we own the handle in this case 856950e428feaccc8164b989ef64e771a99948797aMathias Agopian width = data.readInt32(); 866950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (width < 0) { 876950e428feaccc8164b989ef64e771a99948797aMathias Agopian width = height = stride = format = usage = 0; 886950e428feaccc8164b989ef64e771a99948797aMathias Agopian handle = 0; 896950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 906950e428feaccc8164b989ef64e771a99948797aMathias Agopian height = data.readInt32(); 916950e428feaccc8164b989ef64e771a99948797aMathias Agopian stride = data.readInt32(); 926950e428feaccc8164b989ef64e771a99948797aMathias Agopian format = data.readInt32(); 936950e428feaccc8164b989ef64e771a99948797aMathias Agopian usage = data.readInt32(); 946950e428feaccc8164b989ef64e771a99948797aMathias Agopian handle = data.readNativeHandle(); 956950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 966950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 976950e428feaccc8164b989ef64e771a99948797aMathias Agopian 986950e428feaccc8164b989ef64e771a99948797aMathias AgopianGraphicBuffer::~GraphicBuffer() 996950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1006950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (handle) { 1019042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian if (mOwner == ownHandle) { 1026950e428feaccc8164b989ef64e771a99948797aMathias Agopian native_handle_close(handle); 1036950e428feaccc8164b989ef64e771a99948797aMathias Agopian native_handle_delete(const_cast<native_handle*>(handle)); 1049042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian } else if (mOwner == ownData) { 1056950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 1066950e428feaccc8164b989ef64e771a99948797aMathias Agopian allocator.free(handle); 1076950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1086950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1096950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1106950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1116950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::initCheck() const { 1126950e428feaccc8164b989ef64e771a99948797aMathias Agopian return mInitCheck; 1136950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1146950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1156950e428feaccc8164b989ef64e771a99948797aMathias Agopianandroid_native_buffer_t* GraphicBuffer::getNativeBuffer() const 1166950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1176950e428feaccc8164b989ef64e771a99948797aMathias Agopian return static_cast<android_native_buffer_t*>( 1186950e428feaccc8164b989ef64e771a99948797aMathias Agopian const_cast<GraphicBuffer*>(this)); 1196950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1206950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1216950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, 1226950e428feaccc8164b989ef64e771a99948797aMathias Agopian uint32_t reqUsage) 1236950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1249042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian if (mOwner != ownData) 1259042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian return INVALID_OPERATION; 1269042b4564de5477b18e680c7dce13b587a681dd9Mathias Agopian 1276950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (handle) { 1286950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 1296950e428feaccc8164b989ef64e771a99948797aMathias Agopian allocator.free(handle); 1306950e428feaccc8164b989ef64e771a99948797aMathias Agopian handle = 0; 1316950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1326950e428feaccc8164b989ef64e771a99948797aMathias Agopian return initSize(w, h, f, reqUsage); 1336950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1346950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1356950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, 1366950e428feaccc8164b989ef64e771a99948797aMathias Agopian uint32_t reqUsage) 1376950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1386950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1396950e428feaccc8164b989ef64e771a99948797aMathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1406950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1416950e428feaccc8164b989ef64e771a99948797aMathias Agopian GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); 1426950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); 1436950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (err == NO_ERROR) { 1446950e428feaccc8164b989ef64e771a99948797aMathias Agopian this->width = w; 1456950e428feaccc8164b989ef64e771a99948797aMathias Agopian this->height = h; 1466950e428feaccc8164b989ef64e771a99948797aMathias Agopian this->format = format; 1476950e428feaccc8164b989ef64e771a99948797aMathias Agopian this->usage = reqUsage; 1486950e428feaccc8164b989ef64e771a99948797aMathias Agopian mVStride = 0; 1496950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1506950e428feaccc8164b989ef64e771a99948797aMathias Agopian return err; 1516950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1526950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1536950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::lock(uint32_t usage, void** vaddr) 1546950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1556950e428feaccc8164b989ef64e771a99948797aMathias Agopian const Rect lockBounds(width, height); 1566950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = lock(usage, lockBounds, vaddr); 1576950e428feaccc8164b989ef64e771a99948797aMathias Agopian return res; 1586950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1596950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1606950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) 1616950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1626950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (rect.left < 0 || rect.right > this->width || 1636950e428feaccc8164b989ef64e771a99948797aMathias Agopian rect.top < 0 || rect.bottom > this->height) { 1646950e428feaccc8164b989ef64e771a99948797aMathias Agopian LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 1656950e428feaccc8164b989ef64e771a99948797aMathias Agopian rect.left, rect.top, rect.right, rect.bottom, 1666950e428feaccc8164b989ef64e771a99948797aMathias Agopian this->width, this->height); 1676950e428feaccc8164b989ef64e771a99948797aMathias Agopian return BAD_VALUE; 1686950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1696950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); 1706950e428feaccc8164b989ef64e771a99948797aMathias Agopian return res; 1716950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1726950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1736950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::unlock() 1746950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1756950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = getBufferMapper().unlock(handle); 1766950e428feaccc8164b989ef64e771a99948797aMathias Agopian return res; 1776950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1786950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1796950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) 1806950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1816950e428feaccc8164b989ef64e771a99948797aMathias Agopian void* vaddr; 1826950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t res = GraphicBuffer::lock(usage, &vaddr); 1836950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (res == NO_ERROR && sur) { 1846950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->version = sizeof(GGLSurface); 1856950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->width = width; 1866950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->height = height; 1876950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->stride = stride; 1886950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->format = format; 1896950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->vstride = mVStride; 1906950e428feaccc8164b989ef64e771a99948797aMathias Agopian sur->data = static_cast<GGLubyte*>(vaddr); 1916950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 1926950e428feaccc8164b989ef64e771a99948797aMathias Agopian return res; 1936950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 1946950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1956950e428feaccc8164b989ef64e771a99948797aMathias Agopian 1966950e428feaccc8164b989ef64e771a99948797aMathias Agopianstatus_t GraphicBuffer::writeToParcel(Parcel* reply, 1976950e428feaccc8164b989ef64e771a99948797aMathias Agopian android_native_buffer_t const* buffer) 1986950e428feaccc8164b989ef64e771a99948797aMathias Agopian{ 1996950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (buffer == NULL) 2006950e428feaccc8164b989ef64e771a99948797aMathias Agopian return BAD_VALUE; 2016950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2026950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (buffer->width < 0 || buffer->height < 0) 2036950e428feaccc8164b989ef64e771a99948797aMathias Agopian return BAD_VALUE; 2046950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2056950e428feaccc8164b989ef64e771a99948797aMathias Agopian status_t err = NO_ERROR; 2066950e428feaccc8164b989ef64e771a99948797aMathias Agopian if (buffer->handle == NULL) { 2076950e428feaccc8164b989ef64e771a99948797aMathias Agopian // this buffer doesn't have a handle 2086950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(NO_MEMORY); 2096950e428feaccc8164b989ef64e771a99948797aMathias Agopian } else { 2106950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(buffer->width); 2116950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(buffer->height); 2126950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(buffer->stride); 2136950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(buffer->format); 2146950e428feaccc8164b989ef64e771a99948797aMathias Agopian reply->writeInt32(buffer->usage); 2156950e428feaccc8164b989ef64e771a99948797aMathias Agopian err = reply->writeNativeHandle(buffer->handle); 2166950e428feaccc8164b989ef64e771a99948797aMathias Agopian } 2176950e428feaccc8164b989ef64e771a99948797aMathias Agopian return err; 2186950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 2196950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2206950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2216950e428feaccc8164b989ef64e771a99948797aMathias Agopianvoid GraphicBuffer::setIndex(int index) { 2226950e428feaccc8164b989ef64e771a99948797aMathias Agopian mIndex = index; 2236950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 2246950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2256950e428feaccc8164b989ef64e771a99948797aMathias Agopianint GraphicBuffer::getIndex() const { 2266950e428feaccc8164b989ef64e771a99948797aMathias Agopian return mIndex; 2276950e428feaccc8164b989ef64e771a99948797aMathias Agopian} 2286950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2296950e428feaccc8164b989ef64e771a99948797aMathias Agopian// --------------------------------------------------------------------------- 2306950e428feaccc8164b989ef64e771a99948797aMathias Agopian 2316950e428feaccc8164b989ef64e771a99948797aMathias Agopian}; // namespace android 232