GraphicBuffer.cpp revision 3330b203039dea366d4981db1408a460134b2d2c
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(false), 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(false), 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(const Parcel& data) 66 : BASE(), mOwner(true), mBufferMapper(GraphicBufferMapper::get()), 67 mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) 68{ 69 // we own the handle in this case 70 width = data.readInt32(); 71 if (width < 0) { 72 width = height = stride = format = usage = 0; 73 handle = 0; 74 } else { 75 height = data.readInt32(); 76 stride = data.readInt32(); 77 format = data.readInt32(); 78 usage = data.readInt32(); 79 handle = data.readNativeHandle(); 80 } 81} 82 83GraphicBuffer::~GraphicBuffer() 84{ 85 if (handle) { 86 if (mOwner) { 87 native_handle_close(handle); 88 native_handle_delete(const_cast<native_handle*>(handle)); 89 } else { 90 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 91 allocator.free(handle); 92 } 93 } 94} 95 96status_t GraphicBuffer::initCheck() const { 97 return mInitCheck; 98} 99 100android_native_buffer_t* GraphicBuffer::getNativeBuffer() const 101{ 102 return static_cast<android_native_buffer_t*>( 103 const_cast<GraphicBuffer*>(this)); 104} 105 106status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, 107 uint32_t reqUsage) 108{ 109 if (handle) { 110 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 111 allocator.free(handle); 112 handle = 0; 113 } 114 return initSize(w, h, f, reqUsage); 115} 116 117status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, 118 uint32_t reqUsage) 119{ 120 if (format == PIXEL_FORMAT_RGBX_8888) 121 format = PIXEL_FORMAT_RGBA_8888; 122 123 GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); 124 status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); 125 if (err == NO_ERROR) { 126 this->width = w; 127 this->height = h; 128 this->format = format; 129 this->usage = reqUsage; 130 mVStride = 0; 131 } 132 return err; 133} 134 135status_t GraphicBuffer::lock(uint32_t usage, void** vaddr) 136{ 137 const Rect lockBounds(width, height); 138 status_t res = lock(usage, lockBounds, vaddr); 139 return res; 140} 141 142status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) 143{ 144 if (rect.left < 0 || rect.right > this->width || 145 rect.top < 0 || rect.bottom > this->height) { 146 LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 147 rect.left, rect.top, rect.right, rect.bottom, 148 this->width, this->height); 149 return BAD_VALUE; 150 } 151 status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); 152 return res; 153} 154 155status_t GraphicBuffer::unlock() 156{ 157 status_t res = getBufferMapper().unlock(handle); 158 return res; 159} 160 161status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) 162{ 163 void* vaddr; 164 status_t res = GraphicBuffer::lock(usage, &vaddr); 165 if (res == NO_ERROR && sur) { 166 sur->version = sizeof(GGLSurface); 167 sur->width = width; 168 sur->height = height; 169 sur->stride = stride; 170 sur->format = format; 171 sur->vstride = mVStride; 172 sur->data = static_cast<GGLubyte*>(vaddr); 173 } 174 return res; 175} 176 177 178status_t GraphicBuffer::writeToParcel(Parcel* reply, 179 android_native_buffer_t const* buffer) 180{ 181 if (buffer == NULL) 182 return BAD_VALUE; 183 184 if (buffer->width < 0 || buffer->height < 0) 185 return BAD_VALUE; 186 187 status_t err = NO_ERROR; 188 if (buffer->handle == NULL) { 189 // this buffer doesn't have a handle 190 reply->writeInt32(NO_MEMORY); 191 } else { 192 reply->writeInt32(buffer->width); 193 reply->writeInt32(buffer->height); 194 reply->writeInt32(buffer->stride); 195 reply->writeInt32(buffer->format); 196 reply->writeInt32(buffer->usage); 197 err = reply->writeNativeHandle(buffer->handle); 198 } 199 return err; 200} 201 202 203void GraphicBuffer::setIndex(int index) { 204 mIndex = index; 205} 206 207int GraphicBuffer::getIndex() const { 208 return mIndex; 209} 210 211// --------------------------------------------------------------------------- 212 213}; // namespace android 214