Home | History | Annotate | Download | only in ui
      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 #define LOG_TAG "GraphicBuffer"
     18 
     19 #include <stdlib.h>
     20 #include <stdint.h>
     21 #include <sys/types.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 
     33 namespace android {
     34 
     35 // ===========================================================================
     36 // Buffer and implementation of ANativeWindowBuffer
     37 // ===========================================================================
     38 
     39 GraphicBuffer::GraphicBuffer()
     40     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
     41       mInitCheck(NO_ERROR), mIndex(-1)
     42 {
     43     width  =
     44     height =
     45     stride =
     46     format =
     47     usage  = 0;
     48     handle = NULL;
     49 }
     50 
     51 GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
     52         PixelFormat reqFormat, uint32_t reqUsage)
     53     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
     54       mInitCheck(NO_ERROR), 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 
     65 GraphicBuffer::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), mIndex(-1)
     71 {
     72     width  = w;
     73     height = h;
     74     stride = inStride;
     75     format = inFormat;
     76     usage  = inUsage;
     77     handle = inHandle;
     78 }
     79 
     80 GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
     81     : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
     82       mBufferMapper(GraphicBufferMapper::get()),
     83       mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer)
     84 {
     85     width  = buffer->width;
     86     height = buffer->height;
     87     stride = buffer->stride;
     88     format = buffer->format;
     89     usage  = buffer->usage;
     90     handle = buffer->handle;
     91 }
     92 
     93 GraphicBuffer::~GraphicBuffer()
     94 {
     95     if (handle) {
     96         free_handle();
     97     }
     98 }
     99 
    100 void GraphicBuffer::free_handle()
    101 {
    102     if (mOwner == ownHandle) {
    103         mBufferMapper.unregisterBuffer(handle);
    104         native_handle_close(handle);
    105         native_handle_delete(const_cast<native_handle*>(handle));
    106     } else if (mOwner == ownData) {
    107         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
    108         allocator.free(handle);
    109     }
    110     mWrappedBuffer = 0;
    111 }
    112 
    113 status_t GraphicBuffer::initCheck() const {
    114     return mInitCheck;
    115 }
    116 
    117 void GraphicBuffer::dumpAllocationsToSystemLog()
    118 {
    119     GraphicBufferAllocator::dumpToSystemLog();
    120 }
    121 
    122 ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
    123 {
    124     return static_cast<ANativeWindowBuffer*>(
    125             const_cast<GraphicBuffer*>(this));
    126 }
    127 
    128 status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
    129         uint32_t reqUsage)
    130 {
    131     if (mOwner != ownData)
    132         return INVALID_OPERATION;
    133 
    134     if (handle && w==width && h==height && f==format && reqUsage==usage)
    135         return NO_ERROR;
    136 
    137     if (handle) {
    138         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
    139         allocator.free(handle);
    140         handle = 0;
    141     }
    142     return initSize(w, h, f, reqUsage);
    143 }
    144 
    145 status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
    146         uint32_t reqUsage)
    147 {
    148     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
    149     status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
    150     if (err == NO_ERROR) {
    151         this->width  = w;
    152         this->height = h;
    153         this->format = format;
    154         this->usage  = reqUsage;
    155     }
    156     return err;
    157 }
    158 
    159 status_t GraphicBuffer::lock(uint32_t usage, void** vaddr)
    160 {
    161     const Rect lockBounds(width, height);
    162     status_t res = lock(usage, lockBounds, vaddr);
    163     return res;
    164 }
    165 
    166 status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
    167 {
    168     if (rect.left < 0 || rect.right  > this->width ||
    169         rect.top  < 0 || rect.bottom > this->height) {
    170         LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
    171                 rect.left, rect.top, rect.right, rect.bottom,
    172                 this->width, this->height);
    173         return BAD_VALUE;
    174     }
    175     status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
    176     return res;
    177 }
    178 
    179 status_t GraphicBuffer::unlock()
    180 {
    181     status_t res = getBufferMapper().unlock(handle);
    182     return res;
    183 }
    184 
    185 status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage)
    186 {
    187     void* vaddr;
    188     status_t res = GraphicBuffer::lock(usage, &vaddr);
    189     if (res == NO_ERROR && sur) {
    190         sur->version = sizeof(GGLSurface);
    191         sur->width = width;
    192         sur->height = height;
    193         sur->stride = stride;
    194         sur->format = format;
    195         sur->data = static_cast<GGLubyte*>(vaddr);
    196     }
    197     return res;
    198 }
    199 
    200 size_t GraphicBuffer::getFlattenedSize() const {
    201     return (8 + (handle ? handle->numInts : 0))*sizeof(int);
    202 }
    203 
    204 size_t GraphicBuffer::getFdCount() const {
    205     return handle ? handle->numFds : 0;
    206 }
    207 
    208 status_t GraphicBuffer::flatten(void* buffer, size_t size,
    209         int fds[], size_t count) const
    210 {
    211     size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
    212     if (size < sizeNeeded) return NO_MEMORY;
    213 
    214     size_t fdCountNeeded = GraphicBuffer::getFdCount();
    215     if (count < fdCountNeeded) return NO_MEMORY;
    216 
    217     int* buf = static_cast<int*>(buffer);
    218     buf[0] = 'GBFR';
    219     buf[1] = width;
    220     buf[2] = height;
    221     buf[3] = stride;
    222     buf[4] = format;
    223     buf[5] = usage;
    224     buf[6] = 0;
    225     buf[7] = 0;
    226 
    227     if (handle) {
    228         buf[6] = handle->numFds;
    229         buf[7] = handle->numInts;
    230         native_handle_t const* const h = handle;
    231         memcpy(fds,     h->data,             h->numFds*sizeof(int));
    232         memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
    233     }
    234 
    235     return NO_ERROR;
    236 }
    237 
    238 status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
    239         int fds[], size_t count)
    240 {
    241     if (size < 8*sizeof(int)) return NO_MEMORY;
    242 
    243     int const* buf = static_cast<int const*>(buffer);
    244     if (buf[0] != 'GBFR') return BAD_TYPE;
    245 
    246     const size_t numFds  = buf[6];
    247     const size_t numInts = buf[7];
    248 
    249     const size_t sizeNeeded = (8 + numInts) * sizeof(int);
    250     if (size < sizeNeeded) return NO_MEMORY;
    251 
    252     size_t fdCountNeeded = 0;
    253     if (count < fdCountNeeded) return NO_MEMORY;
    254 
    255     if (handle) {
    256         // free previous handle if any
    257         free_handle();
    258     }
    259 
    260     if (numFds || numInts) {
    261         width  = buf[1];
    262         height = buf[2];
    263         stride = buf[3];
    264         format = buf[4];
    265         usage  = buf[5];
    266         native_handle* h = native_handle_create(numFds, numInts);
    267         memcpy(h->data,          fds,     numFds*sizeof(int));
    268         memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
    269         handle = h;
    270     } else {
    271         width = height = stride = format = usage = 0;
    272         handle = NULL;
    273     }
    274 
    275     mOwner = ownHandle;
    276 
    277     if (handle != 0) {
    278         mBufferMapper.registerBuffer(handle);
    279     }
    280 
    281     return NO_ERROR;
    282 }
    283 
    284 
    285 void GraphicBuffer::setIndex(int index) {
    286     mIndex = index;
    287 }
    288 
    289 int GraphicBuffer::getIndex() const {
    290     return mIndex;
    291 }
    292 
    293 // ---------------------------------------------------------------------------
    294 
    295 }; // namespace android
    296