bool ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfxIntSize& aSize, gfxASurface::gfxContentType aContent, uint32_t aCaps, SurfaceDescriptor* aBuffer) { // Some GL implementations fail to render gralloc textures with // width < 64. There's not much point in gralloc'ing buffers that // small anyway, so fall back on shared memory plus a texture // upload. if (aSize.width < 64) { return false; } PROFILER_LABEL("ShadowLayerForwarder", "PlatformAllocSurfaceDescriptor"); // Gralloc buffers are efficiently mappable as gfxImageSurface, so // no need to check |aCaps & MAP_AS_IMAGE_SURFACE|. MaybeMagicGrallocBufferHandle handle; PGrallocBufferChild* gc; bool defaultRBSwap; if (aCaps & USING_GL_RENDERING_ONLY) { gc = AllocGrallocBuffer(aSize, PixelFormatForContentType(aContent), GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_HW_TEXTURE, &handle); // If you're allocating for USING_GL_RENDERING_ONLY, then we don't flag // this for RB swap. defaultRBSwap = false; } else { gc = AllocGrallocBuffer(aSize, PixelFormatForContentType(aContent), GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE, &handle); // But if you're allocating for non-GL-only rendering, we flag for // RB swap to preserve old behaviour and proper interaction with // cairo. defaultRBSwap = true; } if (!gc) { NS_ERROR("GrallocBufferConstructor failed by returned null"); return false; } else if (handle.Tnull_t == handle.type()) { NS_ERROR("GrallocBufferConstructor failed by returning handle with type Tnull_t"); PGrallocBufferChild::Send__delete__(gc); return false; } GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(gc); gba->InitFromHandle(handle.get_MagicGrallocBufferHandle()); *aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize, /* external */ false, defaultRBSwap); return true; }
/*static*/ PGrallocBufferParent* GrallocBufferActor::Create(const gfxIntSize& aSize, const gfxContentType& aContent, MaybeMagicGrallocBufferHandle* aOutHandle) { SAMPLE_LABEL("GrallocBufferActor", "Create"); GrallocBufferActor* actor = new GrallocBufferActor(); *aOutHandle = null_t(); android::PixelFormat format = PixelFormatForContentType(aContent); sp<GraphicBuffer> buffer( new GraphicBuffer(aSize.width, aSize.height, format, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE)); if (buffer->initCheck() != OK) return actor; size_t bpp = gfxASurface::BytePerPixelFromFormat( gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent)); actor->mAllocBytes = aSize.width * aSize.height * bpp; sCurrentAlloc += actor->mAllocBytes; actor->mGraphicBuffer = buffer; *aOutHandle = MagicGrallocBufferHandle(buffer); return actor; }
/*static*/ PGrallocBufferParent* GrallocBufferActor::Create(const gfxIntSize& aSize, const gfxContentType& aContent, MaybeMagicGrallocBufferHandle* aOutHandle) { SAMPLE_LABEL("GrallocBufferActor", "Create"); GrallocBufferActor* actor = new GrallocBufferActor(); *aOutHandle = null_t(); android::PixelFormat format = PixelFormatForContentType(aContent); sp<GraphicBuffer> buffer( new GraphicBuffer(aSize.width, aSize.height, format, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE)); if (buffer->initCheck() != OK) return actor; actor->mGraphicBuffer = buffer; *aOutHandle = MagicGrallocBufferHandle(buffer); return actor; }