status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) { ALOGE("unsupported pixelformat %d", format); return err; } // the display's pixel format const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t const maxSurfaceDims = min( hw.getMaxTextureSize(), hw.getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); return BAD_VALUE; } PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); const uint32_t hwFlags = hw.getFlags(); mFormat = format; mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); mCurrentOpacity = getOpacityForFormat(format); mSurfaceTexture->setDefaultBufferSize(w, h); mSurfaceTexture->setDefaultBufferFormat(format); mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); int useDither = mFlinger->getUseDithering(); if (useDither) { if (useDither == 2) { mNeedsDithering = true; } else { // we use the red index int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = (layerRedsize > displayRedSize); } } else { mNeedsDithering = false; } return NO_ERROR; }
status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) { ALOGE("unsupported pixelformat %d", format); return err; } uint32_t const maxSurfaceDims = min( mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); return BAD_VALUE; } mFormat = format; mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); mCurrentOpacity = getOpacityForFormat(format); mSurfaceTexture->setDefaultBufferSize(w, h); mSurfaceTexture->setDefaultBufferFormat(format); mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); int displayMinColorDepth; int layerRedsize; switch (mFlinger->getUseDithering()) { case 0: mNeedsDithering = false; break; case 1: displayMinColorDepth = mFlinger->getMinColorDepth(); // we use the red index layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = (layerRedsize > displayMinColorDepth); break; case 2: mNeedsDithering = true; break; } return NO_ERROR; }
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(); }
status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) return err; // the display's pixel format const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t const maxSurfaceDims = min( hw.getMaxTextureSize(), hw.getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { return BAD_VALUE; } PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); const uint32_t hwFlags = hw.getFlags(); mFormat = format; mWidth = w; mHeight = h; mReqFormat = format; mReqWidth = w; mReqHeight = h; mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; // we use the red index int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = layerRedsize > displayRedSize; mSurface = new SurfaceLayer(mFlinger, this); return NO_ERROR; }
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; }