GraphicBuffer.cpp revision 54ba51dff21de666c5ae3bf3abd4f0634ebb0676
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <stdint.h> 19#include <sys/types.h> 20 21#include <binder/Parcel.h> 22 23#include <utils/Errors.h> 24#include <utils/Log.h> 25 26#include <ui/GraphicBuffer.h> 27#include <ui/GraphicBufferAllocator.h> 28#include <ui/GraphicBufferMapper.h> 29#include <ui/PixelFormat.h> 30 31#include <pixelflinger/pixelflinger.h> 32 33namespace android { 34 35// =========================================================================== 36// Buffer and implementation of android_native_buffer_t 37// =========================================================================== 38 39GraphicBuffer::GraphicBuffer() 40 : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 41 mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 42{ 43 width = 44 height = 45 stride = 46 format = 47 usage = 0; 48 handle = NULL; 49} 50 51GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 52 PixelFormat reqFormat, uint32_t reqUsage) 53 : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 54 mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 55{ 56 width = 57 height = 58 stride = 59 format = 60 usage = 0; 61 handle = NULL; 62 mInitCheck = initSize(w, h, reqFormat, reqUsage); 63} 64 65GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 66 PixelFormat inFormat, uint32_t inUsage, 67 uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) 68 : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), 69 mBufferMapper(GraphicBufferMapper::get()), 70 mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 71{ 72 width = w; 73 height = h; 74 stride = inStride; 75 format = inFormat; 76 usage = inUsage; 77 handle = inHandle; 78} 79 80GraphicBuffer::GraphicBuffer(const Parcel& data) 81 : BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()), 82 mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 83{ 84 // we own the handle in this case 85 width = data.readInt32(); 86 if (width < 0) { 87 width = height = stride = format = usage = 0; 88 handle = 0; 89 } else { 90 height = data.readInt32(); 91 stride = data.readInt32(); 92 format = data.readInt32(); 93 usage = data.readInt32(); 94 handle = data.readNativeHandle(); 95 } 96} 97 98GraphicBuffer::~GraphicBuffer() 99{ 100 if (handle) { 101 if (mOwner == ownHandle) { 102 native_handle_close(handle); 103 native_handle_delete(const_cast<native_handle*>(handle)); 104 } else if (mOwner == ownData) { 105 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 106 allocator.free(handle); 107 } 108 } 109} 110 111status_t GraphicBuffer::initCheck() const { 112 return mInitCheck; 113} 114 115android_native_buffer_t* GraphicBuffer::getNativeBuffer() const 116{ 117 return static_cast<android_native_buffer_t*>( 118 const_cast<GraphicBuffer*>(this)); 119} 120 121status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, 122 uint32_t reqUsage) 123{ 124 if (mOwner != ownData) 125 return INVALID_OPERATION; 126 127 if (handle) { 128 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 129 allocator.free(handle); 130 handle = 0; 131 } 132 return initSize(w, h, f, reqUsage); 133} 134 135status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, 136 uint32_t reqUsage) 137{ 138 if (format == PIXEL_FORMAT_RGBX_8888) 139 format = PIXEL_FORMAT_RGBA_8888; 140 141 GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); 142 status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); 143 if (err == NO_ERROR) { 144 this->width = w; 145 this->height = h; 146 this->format = format; 147 this->usage = reqUsage; 148 mVStride = 0; 149 } 150 return err; 151} 152 153status_t GraphicBuffer::lock(uint32_t usage, void** vaddr) 154{ 155 const Rect lockBounds(width, height); 156 status_t res = lock(usage, lockBounds, vaddr); 157 return res; 158} 159 160status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) 161{ 162 if (rect.left < 0 || rect.right > this->width || 163 rect.top < 0 || rect.bottom > this->height) { 164 LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 165 rect.left, rect.top, rect.right, rect.bottom, 166 this->width, this->height); 167 return BAD_VALUE; 168 } 169 status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); 170 return res; 171} 172 173status_t GraphicBuffer::unlock() 174{ 175 status_t res = getBufferMapper().unlock(handle); 176 return res; 177} 178 179status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) 180{ 181 void* vaddr; 182 status_t res = GraphicBuffer::lock(usage, &vaddr); 183 if (res == NO_ERROR && sur) { 184 sur->version = sizeof(GGLSurface); 185 sur->width = width; 186 sur->height = height; 187 sur->stride = stride; 188 sur->format = format; 189 sur->vstride = mVStride; 190 sur->data = static_cast<GGLubyte*>(vaddr); 191 } 192 return res; 193} 194 195 196status_t GraphicBuffer::writeToParcel(Parcel* reply, 197 android_native_buffer_t const* buffer) 198{ 199 if (buffer == NULL) 200 return BAD_VALUE; 201 202 if (buffer->width < 0 || buffer->height < 0) 203 return BAD_VALUE; 204 205 status_t err = NO_ERROR; 206 if (buffer->handle == NULL) { 207 // this buffer doesn't have a handle 208 reply->writeInt32(NO_MEMORY); 209 } else { 210 reply->writeInt32(buffer->width); 211 reply->writeInt32(buffer->height); 212 reply->writeInt32(buffer->stride); 213 reply->writeInt32(buffer->format); 214 reply->writeInt32(buffer->usage); 215 err = reply->writeNativeHandle(buffer->handle); 216 } 217 return err; 218} 219 220 221void GraphicBuffer::setIndex(int index) { 222 mIndex = index; 223} 224 225int GraphicBuffer::getIndex() const { 226 return mIndex; 227} 228 229// --------------------------------------------------------------------------- 230 231}; // namespace android 232