Пример #1
0
LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
        const ISurface::BufferHeap& buffers)
    : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
{
    if (buffers.heap == NULL) {
        // this is allowed, but in this case, it is illegal to receive
        // postBuffer(). The surface just erases the framebuffer with
        // fully transparent pixels.
        mBufferHeap = buffers;
        mLayer.setNeedsBlending(false);
        return;
    }

    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
    if (err != NO_ERROR) {
        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
        mStatus = err;
        return;
    }
    
    PixelFormatInfo info;
    err = getPixelFormatInfo(buffers.format, &info);
    if (err != NO_ERROR) {
        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
                buffers.format, strerror(err));
        mStatus = err;
        return;
    }

    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
        LOGE("LayerBuffer::BufferSource: invalid parameters "
             "(w=%d, h=%d, xs=%d, ys=%d)", 
             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
        mStatus = BAD_VALUE;
        return;
    }

    mBufferHeap = buffers;
    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
    mLayer.forceVisibilityTransaction();
}
Пример #2
0
status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
        PixelFormat format, uint32_t flags)
{
    const sp<MemoryDealer>& allocator(mAllocator);
    if (allocator == NULL)
        return NO_INIT;

    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
            format == mSurface.format))
    { // same format and size, do nothing.
        return NO_ERROR;
    }

    PixelFormatInfo info;
    getPixelFormatInfo(format, &info);

    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
    const uint32_t Bpp = info.bytesPerPixel;
    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
    size_t size = info.getScanlineSize(stride) * h;
    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
        size_t pagesize = getpagesize();
        size = (size + (pagesize-1)) & ~(pagesize-1);
    }

    /* FIXME: we should be able to have a h/v stride because the user of the
     * surface might have stride limitation (for instance h/w codecs often do)
     */
    int32_t vstride = 0;

    mAlignment = alignment;
    mAllocFlags = allocFlags;
    mOffset = 0;
    if (mSize != size) {
        // would be nice to have a reallocate() api
        mBitsMemory.clear(); // free-memory
        mBitsMemory = allocator->allocate(size, allocFlags);
        mSize = size;
    } else {
        // don't erase memory if we didn't have to reallocate
        flags &= ~SECURE_BITS;
    }
    if (mBitsMemory != 0) {
        mOffset = mBitsMemory->offset();
        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
        mSurface.version = sizeof(GGLSurface);
        mSurface.width  = w;
        mSurface.height = h;
        mSurface.stride = stride;
        mSurface.vstride = vstride;
        mSurface.format = format;
        if (flags & SECURE_BITS)
            clear();
    }

    if (mBitsMemory==0 || mSurface.data==0) {
        LOGE("not enough memory for layer bitmap "
             "size=%u (w=%d, h=%d, stride=%d, format=%d)",
             size, int(w), int(h), int(stride), int(format));
        allocator->dump("LayerBitmap");
        mSurface.data = 0;
        mSize = -1U;
        return NO_MEMORY;
    }
    return NO_ERROR;
}