GraphicBuffer.cpp revision 53ec72523a4083b88eaa13e2e720976523a7ebf8
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/* 2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2007 The Android Open Source Project 3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License. 6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at 7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software 11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and 14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License. 15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */ 16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#define LOG_TAG "GraphicBuffer" 18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 19326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <stdlib.h> 20a5577808737a394bdb156fbeb80018d0a4d8438dJason Sams#include <stdint.h> 21326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <sys/types.h> 22326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 23a89371c6f144b9049efe7689105feee2c4a38384Jason Sams#include <utils/Errors.h> 2477d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include <utils/Log.h> 25bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams 26bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <ui/GraphicBuffer.h> 2777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include <ui/GraphicBufferAllocator.h> 2877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include <ui/GraphicBufferMapper.h> 2977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include <ui/PixelFormat.h> 3077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk 31326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android { 32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams// =========================================================================== 34326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams// Buffer and implementation of ANativeWindowBuffer 35d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// =========================================================================== 36326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 37ccc010bb7c0f89e162bf60033968a20be90a903aJason SamsGraphicBuffer::GraphicBuffer() 385fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mInitCheck(NO_ERROR) { 40c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams width = 417d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk height = 42c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams stride = 43326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams format = 44326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams usage = 0; 45326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams handle = NULL; 46326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 479b97c2906aed2b6dea9e0824f91f27c08d3690a7Mathias Agopian 4877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex SakhartchoukGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams PixelFormat reqFormat, uint32_t reqUsage) 50326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 51326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mInitCheck(NO_ERROR) 52d4c25e3c197bc79c8508b76b20611b67ef883138Mathias Agopian{ 53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams width = 54326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams height = 55605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams stride = 56605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams format = 57605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams usage = 0; 58afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk handle = NULL; 59605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams mInitCheck = initSize(w, h, reqFormat, reqUsage); 60605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams} 61605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams 62605048a9f9af925782f6c90bc1cdc5af59e337d8Jason SamsGraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 63605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams PixelFormat inFormat, uint32_t inUsage, 64afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) 65605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), 66605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams mBufferMapper(GraphicBufferMapper::get()), 67605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams mInitCheck(NO_ERROR) 68605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams{ 69605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams width = w; 70605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams height = h; 71605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams stride = inStride; 72605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams format = inFormat; 7377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk usage = inUsage; 7477d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk handle = inHandle; 75afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk} 76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 77bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason SamsGraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) 78bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), 79bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams mBufferMapper(GraphicBufferMapper::get()), 80bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams mInitCheck(NO_ERROR), mWrappedBuffer(buffer) 81bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams{ 82bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams width = buffer->width; 83bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams height = buffer->height; 845c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams stride = buffer->stride; 85326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams format = buffer->format; 86326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams usage = buffer->usage; 87e57691037aea219562ac686429b4b98202aab7bcJason Sams handle = buffer->handle; 88fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams} 8933b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams 90fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason SamsGraphicBuffer::~GraphicBuffer() 91ca3f09c0924e9515901dfd47fa5f95385d53cf80Stephen Hines{ 92ca3f09c0924e9515901dfd47fa5f95385d53cf80Stephen Hines if (handle) { 93fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams free_handle(); 9460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } 9560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams} 9660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 9760709257bbdeb0c50f39b9c8969dc76264d6e142Jason Samsvoid GraphicBuffer::free_handle() 9860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams{ 9960709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams if (mOwner == ownHandle) { 10060709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams mBufferMapper.unregisterBuffer(handle); 10160709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams native_handle_close(handle); 10260709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams native_handle_delete(const_cast<native_handle*>(handle)); 10360709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } else if (mOwner == ownData) { 10460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 10560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams allocator.free(handle); 10660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } 10760709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams mWrappedBuffer = 0; 108605048a9f9af925782f6c90bc1cdc5af59e337d8Jason Sams} 1096b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 110e57691037aea219562ac686429b4b98202aab7bcJason Samsstatus_t GraphicBuffer::initCheck() const { 111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return mInitCheck; 112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 114326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid GraphicBuffer::dumpAllocationsToSystemLog() 115ccc010bb7c0f89e162bf60033968a20be90a903aJason Sams{ 1165fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams GraphicBufferAllocator::dumpToSystemLog(); 117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 118c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 119d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const 120326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 121326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return static_cast<ANativeWindowBuffer*>( 122c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams const_cast<GraphicBuffer*>(this)); 1237d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk} 124326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 125326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsstatus_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, 126326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t reqUsage) 12760709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams{ 12860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams if (mOwner != ownData) 12960709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams return INVALID_OPERATION; 13060709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 131d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (handle && w==width && h==height && f==format && reqUsage==usage) 132326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return NO_ERROR; 133326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 134326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (handle) { 13560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 13660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams allocator.free(handle); 13760709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams handle = 0; 13860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } 139d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return initSize(w, h, f, reqUsage); 140326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 141a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams 142889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchoukstatus_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, 143326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t reqUsage) 14486f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams{ 14586f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); 1461c769c3d0e5f08e78ecdb4508c6bc69fcb69bfa8Dianne Hackborn status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); 147158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams if (err == NO_ERROR) { 148741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams this->width = w; 14986f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams this->height = h; 150a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams this->format = format; 151a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams this->usage = reqUsage; 1528ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams } 153aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams return err; 154aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams} 15587319de2b16a185cf360827c96a42cf1fcaae744Jason Sams 156c61346b91434307c5003029017b54ce9c49112beJason Samsstatus_t GraphicBuffer::lock(uint32_t usage, void** vaddr) 1578c401effb0837155fc39ca0364f57a882d127d38Jason Sams{ 1588c401effb0837155fc39ca0364f57a882d127d38Jason Sams const Rect lockBounds(width, height); 1598c401effb0837155fc39ca0364f57a882d127d38Jason Sams status_t res = lock(usage, lockBounds, vaddr); 1608c401effb0837155fc39ca0364f57a882d127d38Jason Sams return res; 1618ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams} 1628ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams 1638ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Samsstatus_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) 1648ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams{ 1658ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams if (rect.left < 0 || rect.right > this->width || 1668ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams rect.top < 0 || rect.bottom > this->height) { 167ccc010bb7c0f89e162bf60033968a20be90a903aJason Sams ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 1688ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams rect.left, rect.top, rect.right, rect.bottom, 1698ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams this->width, this->height); 1705fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams return BAD_VALUE; 1715fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams } 1725fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); 173d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return res; 174d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 175d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 1768ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Samsstatus_t GraphicBuffer::lockYCbCr(uint32_t usage, android_ycbcr *ycbcr) 177771565f47fc44608444c00aa8fa3bda769ceaeceJason Sams{ 178771565f47fc44608444c00aa8fa3bda769ceaeceJason Sams const Rect lockBounds(width, height); 179e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams status_t res = lockYCbCr(usage, lockBounds, ycbcr); 18087319de2b16a185cf360827c96a42cf1fcaae744Jason Sams return res; 181fcd3192ebff8ab58d841836b7e94361d0998338cJason Sams} 18224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 18324371d93cdb6999971c4058f78974da3c3d5fc64Jason Samsstatus_t GraphicBuffer::lockYCbCr(uint32_t usage, const Rect& rect, 18424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams android_ycbcr *ycbcr) 18524371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams{ 18624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams if (rect.left < 0 || rect.right > this->width || 18724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams rect.top < 0 || rect.bottom > this->height) { 18824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 18924371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams rect.left, rect.top, rect.right, rect.bottom, 19024371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams this->width, this->height); 19124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams return BAD_VALUE; 19224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams } 19324371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams status_t res = getBufferMapper().lockYCbCr(handle, usage, rect, ycbcr); 19424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams return res; 1951d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams} 19624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 1971fddd90849deaae89b546ff492c345d485bbce42Jason Samsstatus_t GraphicBuffer::unlock() 1981fddd90849deaae89b546ff492c345d485bbce42Jason Sams{ 1991fddd90849deaae89b546ff492c345d485bbce42Jason Sams status_t res = getBufferMapper().unlock(handle); 2001fddd90849deaae89b546ff492c345d485bbce42Jason Sams return res; 201cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams} 202886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk 203886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouksize_t GraphicBuffer::getFlattenedSize() const { 2040cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk return (8 + (handle ? handle->numInts : 0))*sizeof(int); 2051fddd90849deaae89b546ff492c345d485bbce42Jason Sams} 20676371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 20713e2634a71a30d289ed8d821aef61c7d1687460eJason Samssize_t GraphicBuffer::getFdCount() const { 20887319de2b16a185cf360827c96a42cf1fcaae744Jason Sams return handle ? handle->numFds : 0; 20987319de2b16a185cf360827c96a42cf1fcaae744Jason Sams} 21013e2634a71a30d289ed8d821aef61c7d1687460eJason Sams 211e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Samsstatus_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { 212e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); 213ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams if (size < sizeNeeded) return NO_MEMORY; 2140f7785c4542855ad5e22e6b720c6bdad1817ac61Jason Sams 215dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk size_t fdCountNeeded = GraphicBuffer::getFdCount(); 216886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk if (count < fdCountNeeded) return NO_MEMORY; 217383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk 218383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk int* buf = static_cast<int*>(buffer); 219383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk buf[0] = 'GBFR'; 2202d791976a2b937017423519d9f9a4928fc31dae2Alex Sakhartchouk buf[1] = width; 221ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams buf[2] = height; 2227b3e9bd825901e33661e3c385e3e7c6f40ca6000Alex Sakhartchouk buf[3] = stride; 2237b3e9bd825901e33661e3c385e3e7c6f40ca6000Alex Sakhartchouk buf[4] = format; 2247bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams buf[5] = usage; 225326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams buf[6] = 0; 226326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams buf[7] = 0; 227326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 228afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams if (handle) { 229afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams buf[6] = handle->numFds; 230afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams buf[7] = handle->numInts; 231afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams native_handle_t const* const h = handle; 232afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams memcpy(fds, h->data, h->numFds*sizeof(int)); 233afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int)); 234afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams } 2356b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 236afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded); 237afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams size -= sizeNeeded; 238afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams fds += handle->numFds; 239afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams count -= handle->numFds; 240afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams 241afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams return NO_ERROR; 242afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams} 243afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams 244afcb25c65e8145d15aaf50a0ca38333954a97000Jason Samsstatus_t GraphicBuffer::unflatten( 245afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams void const*& buffer, size_t& size, int const*& fds, size_t& count) { 246afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams if (size < 8*sizeof(int)) return NO_MEMORY; 247afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams 2484815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams int const* buf = static_cast<int const*>(buffer); 2494815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams if (buf[0] != 'GBFR') return BAD_TYPE; 2504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams 2514815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams const size_t numFds = buf[6]; 2524815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams const size_t numInts = buf[7]; 2534815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams 2544815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams const size_t sizeNeeded = (8 + numInts) * sizeof(int); 2554815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams if (size < sizeNeeded) return NO_MEMORY; 2564815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams 257ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams size_t fdCountNeeded = 0; 258ef21edcc70fc2734a3dc7995d3c3af1f90d16ef8Jason Sams if (count < fdCountNeeded) return NO_MEMORY; 2590f7785c4542855ad5e22e6b720c6bdad1817ac61Jason Sams 260dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk if (handle) { 261886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk // free previous handle if any 262afcb25c65e8145d15aaf50a0ca38333954a97000Jason Sams free_handle(); 263326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 2647b3e9bd825901e33661e3c385e3e7c6f40ca6000Alex Sakhartchouk 265613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams if (numFds || numInts) { 266613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams width = buf[1]; 2672dca84dd6c07992f78ad050177975f16486dd77eJason Sams height = buf[2]; 2684820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams stride = buf[3]; 269613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams format = buf[4]; 270326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams usage = buf[5]; 271326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams native_handle* h = native_handle_create(numFds, numInts); 27286f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams memcpy(h->data, fds, numFds*sizeof(int)); 27387319de2b16a185cf360827c96a42cf1fcaae744Jason Sams memcpy(h->data + numFds, &buf[8], numInts*sizeof(int)); 274326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams handle = h; 275326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } else { 276158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams width = height = stride = format = usage = 0; 277326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams handle = NULL; 278326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 279326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 280326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mOwner = ownHandle; 281ccc010bb7c0f89e162bf60033968a20be90a903aJason Sams 2825fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams if (handle != 0) { 283d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk status_t err = mBufferMapper.registerBuffer(handle); 2845086938044e0a9b6b1138f915d0d252fe046e102Jason Sams if (err != NO_ERROR) { 2850cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk width = height = stride = format = usage = 0; 2860cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk handle = NULL; 287326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGE("unflatten: registerBuffer failed: %s (%d)", 288326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams strerror(-err), err); 2895c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams return err; 290326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 2915c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams } 2925c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 29333b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded); 294326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams size -= sizeNeeded; 2952dca84dd6c07992f78ad050177975f16486dd77eJason Sams fds += numFds; 296326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams count -= numFds; 297326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 2987bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams return NO_ERROR; 299326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 3001c769c3d0e5f08e78ecdb4508c6bc69fcb69bfa8Dianne Hackborn 301a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams// --------------------------------------------------------------------------- 302a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams 30324371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams}; // namespace android 30424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams