Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions. Authors: gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical gfx/layers/d3d* - D3D9/D3D10 - bas gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas gfx/layers/composite/* - CompositeLayers - nrc,nical gfx/layers/client/* - Client - nrc,nical,bas gfx/layers/*Image* - nical gfx/layers/ipc ipc - IPC - nical gfx/layers/opengl - CompositorOGL - nrc,nical gfx/2d - bas,nrc gfx/gl - GLContext - bjacob dom/* layout/* - DOM - mattwoodrow
This commit is contained in:
372
gfx/layers/client/TextureClient.cpp
Normal file
372
gfx/layers/client/TextureClient.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
|
||||
#include "mozilla/layers/ImageClient.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/ContentClient.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/layers/TextureChild.h"
|
||||
#include "BasicLayers.h" // for PaintContext
|
||||
#include "ShmemYCbCrImage.h"
|
||||
#include "gfxReusableSurfaceWrapper.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
TextureClient::TextureClient(CompositableForwarder* aForwarder,
|
||||
CompositableType aCompositableType)
|
||||
: mForwarder(aForwarder)
|
||||
, mTextureChild(nullptr)
|
||||
, mAccessMode(ACCESS_READ_WRITE)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureClient);
|
||||
mTextureInfo.mCompositableType = aCompositableType;
|
||||
}
|
||||
|
||||
TextureClient::~TextureClient()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureClient);
|
||||
MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::T__None, "Need to release surface!");
|
||||
|
||||
if (mTextureChild) {
|
||||
static_cast<TextureChild*>(mTextureChild)->SetClient(nullptr);
|
||||
static_cast<TextureChild*>(mTextureChild)->Destroy();
|
||||
mTextureChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::Destroyed()
|
||||
{
|
||||
// The owning layer must be locked at some point in the chain of callers
|
||||
// by calling Hold.
|
||||
mForwarder->DestroyedThebesBuffer(mDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::Updated()
|
||||
{
|
||||
if (mDescriptor.type() != SurfaceDescriptor::T__None &&
|
||||
mDescriptor.type() != SurfaceDescriptor::Tnull_t) {
|
||||
mForwarder->UpdateTexture(this, SurfaceDescriptor(mDescriptor));
|
||||
mDescriptor = SurfaceDescriptor();
|
||||
} else {
|
||||
NS_WARNING("Trying to send a null SurfaceDescriptor.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SetIPDLActor(PTextureChild* aChild) {
|
||||
mTextureChild = aChild;
|
||||
}
|
||||
|
||||
|
||||
TextureClientShmem::TextureClientShmem(CompositableForwarder* aForwarder,
|
||||
CompositableType aCompositableType)
|
||||
: TextureClient(aForwarder, aCompositableType)
|
||||
, mSurface(nullptr)
|
||||
, mSurfaceAsImage(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmem::ReleaseResources()
|
||||
{
|
||||
if (mSurface) {
|
||||
mSurface = nullptr;
|
||||
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
|
||||
}
|
||||
|
||||
if (mTextureInfo.mTextureFlags & HostRelease) {
|
||||
mDescriptor = SurfaceDescriptor();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSurfaceDescriptorValid(mDescriptor)) {
|
||||
mForwarder->DestroySharedSurface(&mDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aContentType)
|
||||
{
|
||||
if (aSize != mSize ||
|
||||
aContentType != mContentType ||
|
||||
!IsSurfaceDescriptorValid(mDescriptor)) {
|
||||
ReleaseResources();
|
||||
|
||||
mContentType = aContentType;
|
||||
mSize = aSize;
|
||||
|
||||
if (!mForwarder->AllocSurfaceDescriptor(gfxIntSize(mSize.width, mSize.height),
|
||||
mContentType, &mDescriptor)) {
|
||||
NS_WARNING("creating SurfaceDescriptor failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmem::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
if (IsSurfaceDescriptorValid(aDescriptor)) {
|
||||
ReleaseResources();
|
||||
mDescriptor = aDescriptor;
|
||||
} else {
|
||||
EnsureAllocated(mSize, mContentType);
|
||||
}
|
||||
|
||||
mSurface = nullptr;
|
||||
|
||||
NS_ASSERTION(mDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc ||
|
||||
mDescriptor.type() == SurfaceDescriptor::TShmem ||
|
||||
mDescriptor.type() == SurfaceDescriptor::TRGBImage,
|
||||
"Invalid surface descriptor");
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
TextureClientShmem::GetSurface()
|
||||
{
|
||||
if (!mSurface) {
|
||||
if (!IsSurfaceDescriptorValid(mDescriptor)) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mAccessMode == ACCESS_READ_WRITE || mAccessMode == ACCESS_READ_ONLY);
|
||||
OpenMode mode = mAccessMode == ACCESS_READ_WRITE
|
||||
? OPEN_READ_WRITE
|
||||
: OPEN_READ_ONLY;
|
||||
mSurface = ShadowLayerForwarder::OpenDescriptor(mode, mDescriptor);
|
||||
}
|
||||
|
||||
return mSurface.get();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmem::Unlock()
|
||||
{
|
||||
mSurface = nullptr;
|
||||
mSurfaceAsImage = nullptr;
|
||||
|
||||
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
TextureClientShmem::LockImageSurface()
|
||||
{
|
||||
if (!mSurfaceAsImage) {
|
||||
mSurfaceAsImage = GetSurface()->GetAsImageSurface();
|
||||
}
|
||||
|
||||
return mSurfaceAsImage.get();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmemYCbCr::ReleaseResources()
|
||||
{
|
||||
GetForwarder()->DestroySharedSurface(&mDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmemYCbCr::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TYCbCrImage);
|
||||
|
||||
if (IsSurfaceDescriptorValid(mDescriptor)) {
|
||||
GetForwarder()->DestroySharedSurface(&mDescriptor);
|
||||
}
|
||||
mDescriptor = aDescriptor;
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(mDescriptor));
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmemYCbCr::SetDescriptorFromReply(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TYCbCrImage);
|
||||
SharedPlanarYCbCrImage* shYCbCr = SharedPlanarYCbCrImage::FromSurfaceDescriptor(aDescriptor);
|
||||
if (shYCbCr) {
|
||||
shYCbCr->Release();
|
||||
mDescriptor = SurfaceDescriptor();
|
||||
} else {
|
||||
SetDescriptor(aDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientShmemYCbCr::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
NS_RUNTIMEABORT("not enough arguments to do this (need both Y and CbCr sizes)");
|
||||
}
|
||||
|
||||
|
||||
TextureClientTile::TextureClientTile(const TextureClientTile& aOther)
|
||||
: TextureClient(aOther.mForwarder, aOther.mTextureInfo.mCompositableType)
|
||||
, mSurface(aOther.mSurface)
|
||||
{}
|
||||
|
||||
TextureClientTile::~TextureClientTile()
|
||||
{}
|
||||
|
||||
TextureClientTile::TextureClientTile(CompositableForwarder* aForwarder, CompositableType aCompositableType)
|
||||
: TextureClient(aForwarder, aCompositableType)
|
||||
, mSurface(nullptr)
|
||||
{
|
||||
mTextureInfo.mTextureHostFlags = TEXTURE_HOST_TILED;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
|
||||
{
|
||||
if (!mSurface ||
|
||||
mSurface->Format() != gfxPlatform::GetPlatform()->OptimalFormatForContent(aType)) {
|
||||
gfxImageSurface* tmpTile = new gfxImageSurface(gfxIntSize(aSize.width, aSize.height),
|
||||
gfxPlatform::GetPlatform()->OptimalFormatForContent(aType),
|
||||
aType != gfxASurface::CONTENT_COLOR);
|
||||
mSurface = new gfxReusableSurfaceWrapper(tmpTile);
|
||||
mContentType = aType;
|
||||
}
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
TextureClientTile::LockImageSurface()
|
||||
{
|
||||
// Use the gfxReusableSurfaceWrapper, which will reuse the surface
|
||||
// if the compositor no longer has a read lock, otherwise the surface
|
||||
// will be copied into a new writable surface.
|
||||
gfxImageSurface* writableSurface = nullptr;
|
||||
mSurface = mSurface->GetWritable(&writableSurface);
|
||||
return writableSurface;
|
||||
}
|
||||
|
||||
bool AutoLockShmemClient::Update(Image* aImage,
|
||||
uint32_t aContentFlags,
|
||||
gfxPattern* pat)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface = pat->GetSurface();
|
||||
if (!aImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pattern = pat ? pat : new gfxPattern(surface);
|
||||
|
||||
gfxIntSize size = aImage->GetSize();
|
||||
|
||||
gfxASurface::gfxContentType contentType = gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
bool isOpaque = (aContentFlags & Layer::CONTENT_OPAQUE);
|
||||
if (surface) {
|
||||
contentType = surface->GetContentType();
|
||||
}
|
||||
if (contentType != gfxASurface::CONTENT_ALPHA &&
|
||||
isOpaque) {
|
||||
contentType = gfxASurface::CONTENT_COLOR;
|
||||
}
|
||||
mTextureClient->EnsureAllocated(gfx::IntSize(size.width, size.height), contentType);
|
||||
|
||||
OpenMode mode = mTextureClient->GetAccessMode() == TextureClient::ACCESS_READ_WRITE
|
||||
? OPEN_READ_WRITE
|
||||
: OPEN_READ_ONLY;
|
||||
nsRefPtr<gfxASurface> tmpASurface =
|
||||
ShadowLayerForwarder::OpenDescriptor(mode,
|
||||
*mTextureClient->LockSurfaceDescriptor());
|
||||
if (!tmpASurface) {
|
||||
return false;
|
||||
}
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(tmpASurface.get());
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, size.width, size.height)),
|
||||
1.0, tmpCtx, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AutoLockYCbCrClient::Update(PlanarYCbCrImage* aImage)
|
||||
{
|
||||
MOZ_ASSERT(aImage);
|
||||
MOZ_ASSERT(mDescriptor);
|
||||
|
||||
const PlanarYCbCrImage::Data *data = aImage->GetData();
|
||||
NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EnsureTextureClient(aImage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
|
||||
|
||||
ShmemYCbCrImage shmemImage(shmem);
|
||||
if (!shmemImage.CopyData(data->mYChannel, data->mCbChannel, data->mCrChannel,
|
||||
data->mYSize, data->mYStride,
|
||||
data->mCbCrSize, data->mCbCrStride,
|
||||
data->mYSkip, data->mCbSkip)) {
|
||||
NS_WARNING("Failed to copy image data!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutoLockYCbCrClient::EnsureTextureClient(PlanarYCbCrImage* aImage)
|
||||
{
|
||||
MOZ_ASSERT(aImage);
|
||||
if (!aImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PlanarYCbCrImage::Data *data = aImage->GetData();
|
||||
NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needsAllocation = false;
|
||||
if (mDescriptor->type() != SurfaceDescriptor::TYCbCrImage) {
|
||||
needsAllocation = true;
|
||||
} else {
|
||||
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
|
||||
ShmemYCbCrImage shmemImage(shmem);
|
||||
if (shmemImage.GetYSize() != data->mYSize ||
|
||||
shmemImage.GetCbCrSize() != data->mCbCrSize) {
|
||||
needsAllocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!needsAllocation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mTextureClient->ReleaseResources();
|
||||
|
||||
ipc::SharedMemory::SharedMemoryType shmType = OptimalShmemType();
|
||||
size_t size = ShmemYCbCrImage::ComputeMinBufferSize(data->mYSize,
|
||||
data->mCbCrSize);
|
||||
ipc::Shmem shmem;
|
||||
if (!mTextureClient->GetForwarder()->AllocUnsafeShmem(size, shmType, &shmem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ShmemYCbCrImage::InitializeBufferInfo(shmem.get<uint8_t>(),
|
||||
data->mYSize,
|
||||
data->mCbCrSize);
|
||||
|
||||
|
||||
*mDescriptor = YCbCrImage(shmem, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user