Bug 858914 - New texture classes + OGL backend (preffed off). r=bas, nrc

This commit is contained in:
Nicolas Silva 2013-07-30 11:59:51 +02:00
parent ea15a7a7de
commit 2b6a0c31a2
72 changed files with 3710 additions and 291 deletions

View File

@ -360,14 +360,14 @@ MediaPluginReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight
return nullptr;
}
nsRefPtr<mozilla::layers::DeprecatedSharedRGBImage> rgbImage;
nsRefPtr<Image> rgbImage;
switch(aColorFormat) {
case MPAPI::RGB565:
rgbImage = mozilla::layers::DeprecatedSharedRGBImage::Create(mImageContainer,
nsIntSize(aWidth, aHeight),
gfxASurface::ImageFormatRGB16_565);
rgbImage = mozilla::layers::CreateSharedRGBImage(mImageContainer,
nsIntSize(aWidth, aHeight),
gfxASurface::ImageFormatRGB16_565);
mImage = rgbImage;
return rgbImage->GetBuffer();
return rgbImage->AsSharedImage()->GetBuffer();
case MPAPI::YCbCr:
default:
NS_NOTREACHED("Color format not supported");

View File

@ -8,6 +8,7 @@
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "gfx2DGlue.h"
namespace mozilla {
namespace gl {
@ -22,6 +23,25 @@ TextureImage::Create(GLContext* gl,
return gl->CreateTextureImage(size, contentType, wrapMode, flags);
}
bool
TextureImage::UpdateFromDataSource(gfx::DataSourceSurface *aSurface,
const nsIntRegion* aDestRegion,
const gfx::IntPoint* aSrcPoint)
{
nsIntRegion destRegion = aDestRegion ? *aDestRegion
: nsIntRect(0, 0,
aSurface->GetSize().width,
aSurface->GetSize().height);
nsIntPoint thebesSrcPoint = aSrcPoint ? nsIntPoint(aSrcPoint->x, aSrcPoint->y)
: nsIntPoint(0, 0);
RefPtr<gfxASurface> thebesSurf
= new gfxImageSurface(aSurface->GetData(),
ThebesIntSize(aSurface->GetSize()),
aSurface->Stride(),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
return DirectUpdate(thebesSurf, destRegion, thebesSrcPoint);
}
BasicTextureImage::~BasicTextureImage()
{
GLContext *ctx = mGLContext;

View File

@ -12,6 +12,13 @@
#include "gfxASurface.h"
#include "GLContextTypes.h"
#include "gfxPattern.h"
#include "mozilla/gfx/Rect.h"
namespace mozilla {
namespace gfx {
class DataSourceSurface;
}
}
namespace mozilla {
namespace gl {
@ -164,6 +171,10 @@ public:
* aFrom - offset in the source to update from
*/
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)) = 0;
// Moz2D equivalent
bool UpdateFromDataSource(gfx::DataSourceSurface *aSurf,
const nsIntRegion* aDstRegion = nullptr,
const gfx::IntPoint* aSrcOffset = nullptr);
virtual void BindTexture(GLenum aTextureUnit) = 0;
virtual void ReleaseTexture() {}

View File

@ -10,9 +10,8 @@
#include "mozilla/gfx/Matrix.h"
#include "gfxMatrix.h"
#include "Layers.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/RefPtr.h"
#include "mozilla/layers/CompositorTypes.h"
/**
* Different elements of a web pages are rendered into separate "layers" before
@ -113,6 +112,9 @@ struct Effect;
struct EffectChain;
class Image;
class ISurfaceAllocator;
class NewTextureSource;
class DataTextureSource;
class CompositingRenderTarget;
enum SurfaceInitMode
{
@ -179,9 +181,19 @@ public:
MOZ_COUNT_DTOR(Compositor);
}
virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = 0) = 0;
virtual bool Initialize() = 0;
virtual void Destroy() = 0;
/**
* Return true if the effect type is supported.
*
* By default Compositor implementations should support all effects but in
* some rare cases it is not possible to support an effect efficiently.
* This is the case for BasicCompositor with EffectYCbCr.
*/
virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
/**
* Request a texture host identifier that may be used for creating textures
* across process or thread boundaries that are compatible with this

View File

@ -19,26 +19,76 @@ const SurfaceDescriptorType SURFACEDESCRIPTOR_UNKNOWN = 0;
* side to host side when textures and compositables are created. Usually set
* by the compositableCient, they may be modified by either the compositable or
* texture clients.
*
* XXX - switch to all caps constant names which seems to be the standard in gecko
*/
typedef uint32_t TextureFlags;
// Use nearest-neighbour texture filtering (as opposed to linear filtering).
const TextureFlags UseNearestFilter = 0x1;
const TextureFlags UseNearestFilter = 1 << 0;
// The texture should be flipped around the y-axis when composited.
const TextureFlags NeedsYFlip = 0x2;
const TextureFlags NeedsYFlip = 1 << 1;
// Force the texture to be represented using a single tile (note that this means
// tiled textures, not tiled layers).
const TextureFlags ForceSingleTile = 0x4;
const TextureFlags ForceSingleTile = 1 << 2;
// Allow using 'repeat' mode for wrapping.
const TextureFlags AllowRepeat = 0x8;
const TextureFlags AllowRepeat = 1 << 3;
// The texture represents a tile which is newly created.
const TextureFlags NewTile = 0x10;
// The host is responsible for tidying up any shared resources.
const TextureFlags HostRelease = 0x20;
const TextureFlags NewTile = 1 << 4;
// The texture is part of a component-alpha pair
const TextureFlags ComponentAlpha = 0x40;
// The shared resources are owned by client
const TextureFlags OwnByClient = 0x80;
const TextureFlags ComponentAlpha = 1 << 5;
// The buffer will be treated as if the RB bytes are swapped.
// This is useful for rendering using Cairo/Thebes, because there is no
// BGRX Android pixel format, and so we have to do byte swapping.
//
// For example, if the GraphicBuffer has an Android pixel format of
// PIXEL_FORMAT_RGBA_8888 and isRBSwapped is true, when it is sampled
// (for example, with GL), a BGRA shader should be used.
const TextureFlags TEXTURE_RB_SWAPPED = 1 << 6;
// A texture host that supports tiling
const TextureFlags TEXTURE_FRONT = 1 << 12;
// A texture host on white for component alpha
const TextureFlags TEXTURE_ON_WHITE = 1 << 13;
// A texture host on black for component alpha
const TextureFlags TEXTURE_ON_BLACK = 1 << 14;
// A texture host that supports tiling
const TextureFlags TEXTURE_TILE = 1 << 15;
// Texture contents should be initialized
// from the previous texture.
const TextureFlags TEXTURE_COPY_PREVIOUS = 1 << 24;
// Who is responsible for deallocating the shared data.
// if none of the following two flags is set, the shared data will not be
// deallocated by the layers system. It is not necessarily a leak, it could
// be a choice from another part of gecko that wants to keep the data alive
// for some reason. The default behaviour is to deallocate on the host side.
const TextureFlags TEXTURE_DEALLOCATE_CLIENT = 1 << 25;
const TextureFlags TEXTURE_DEALLOCATE_HOST = 1 << 26;
// After being shared ith the compositor side, an immutable texture is never
// modified, it can only be read. It is safe to not Lock/Unlock immutable
// textures.
const TextureFlags TEXTURE_IMMUTABLE = 1 << 27;
// the default flags
const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_DEALLOCATE_HOST
| TEXTURE_FRONT;
/**
* See gfx/layers/Effects.h
*/
enum EffectTypes
{
EFFECT_MASK,
EFFECT_MAX_SECONDARY, // sentinel for the count of secondary effect types
EFFECT_BGRX,
EFFECT_RGBX,
EFFECT_BGRA,
EFFECT_RGBA,
EFFECT_YCBCR,
EFFECT_COMPONENT_ALPHA,
EFFECT_SOLID_COLOR,
EFFECT_RENDER_TARGET,
EFFECT_MAX //sentinel for the count of all effect types
};
/**
* The kind of memory held by the texture client/host pair. This will
@ -49,7 +99,7 @@ enum DeprecatedTextureClientType
{
TEXTURE_CONTENT, // dynamically drawn content
TEXTURE_SHMEM, // shared memory
TEXTURE_YCBCR, // YCbCr in a shmem
TEXTURE_YCBCR, // Deprecated YCbCr texture
TEXTURE_SHARED_GL, // GLContext::SharedTextureHandle
TEXTURE_SHARED_GL_EXTERNAL, // GLContext::SharedTextureHandle, the ownership of
// the SurfaceDescriptor passed to the texture
@ -63,14 +113,17 @@ enum DeprecatedTextureClientType
enum CompositableType
{
BUFFER_UNKNOWN,
// the deprecated compositable types
BUFFER_IMAGE_SINGLE, // image/canvas with a single texture, single buffered
BUFFER_IMAGE_BUFFERED, // image/canvas, double buffered
BUFFER_IMAGE_BUFFERED, // canvas, double buffered
BUFFER_BRIDGE, // image bridge protocol
BUFFER_CONTENT, // thebes layer interface, single buffering
BUFFER_CONTENT_DIRECT, // thebes layer interface, double buffering
BUFFER_CONTENT_INC, // thebes layer interface, only sends incremental
// updates to a texture on the compositor side.
BUFFER_TILED, // tiled thebes layer
// the new compositable types
COMPOSITABLE_IMAGE, // image with single buffering
BUFFER_COUNT
};
@ -112,6 +165,8 @@ struct TextureFactoryIdentifier
/**
* Identify a texture to a compositable. Many textures can have the same id, but
* the id is unique for any texture owned by a particular compositable.
* XXX - This is now redundant with TextureFlags. it ill be removed along with
* deprecated texture classes.
*/
typedef uint32_t TextureIdentifier;
const TextureIdentifier TextureFront = 1;
@ -122,6 +177,9 @@ const TextureIdentifier TextureOnWhiteBack = 4;
/**
* Information required by the compositor from the content-side for creating or
* using compositables and textures.
* XXX - TextureInfo is a bad name: this information is useful for the compositable,
* not the Texture. And ith new Textures, only the compositable type is really
* useful. This may (should) be removed in the near future.
*/
struct TextureInfo
{
@ -155,8 +213,8 @@ struct TextureInfo
* See ShadowLayerForwarder::OpenDescriptor for example.
*/
enum OpenMode {
OPEN_READ_ONLY,
OPEN_READ_WRITE
OPEN_READ_ONLY = 0x1,
OPEN_READ_WRITE = 0x2
};
// The kinds of mask texture a shader can support

View File

@ -8,6 +8,7 @@
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
#include "LayersLogging.h"
#include "mozilla/RefPtr.h"
@ -30,22 +31,6 @@ namespace layers {
* to the compositor by the compositable host as a parameter to DrawQuad.
*/
enum EffectTypes
{
EFFECT_MASK,
EFFECT_MAX_SECONDARY, // sentinel for the count of secondary effect types
EFFECT_BGRX,
EFFECT_RGBX,
EFFECT_BGRA,
EFFECT_RGBA,
EFFECT_YCBCR,
EFFECT_COMPONENT_ALPHA,
EFFECT_SOLID_COLOR,
EFFECT_RENDER_TARGET,
EFFECT_MAX //sentinel for the count of all effect types
};
struct Effect : public RefCounted<Effect>
{
Effect(EffectTypes aType) : mType(aType) {}

View File

@ -123,7 +123,7 @@ ImageContainer::ImageContainer(int flag)
if (flag == ENABLE_ASYNC && ImageBridgeChild::IsCreated()) {
// the refcount of this ImageClient is 1. we don't use a RefPtr here because the refcount
// of this class must be done on the ImageBridge thread.
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(BUFFER_IMAGE_BUFFERED).drop();
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(BUFFER_IMAGE_SINGLE).drop();
MOZ_ASSERT(mImageClient);
}
}

View File

@ -35,6 +35,8 @@ namespace layers {
class ImageClient;
class SharedPlanarYCbCrImage;
class DeprecatedSharedPlanarYCbCrImage;
class TextureClient;
class SurfaceDescriptor;
struct ImageBackendData
{
@ -44,6 +46,18 @@ protected:
ImageBackendData() {}
};
// sadly we'll need this until we get rid of Deprected image classes
class ISharedImage {
public:
virtual uint8_t* GetBuffer() = 0;
/**
* For use with the CompositableClient only (so that the later can
* synchronize the TextureClient with the TextureHost).
*/
virtual TextureClient* GetTextureClient() = 0;
};
/**
* A class representing a buffer of pixel data. The data can be in one
* of various formats including YCbCr.
@ -64,12 +78,17 @@ class Image {
public:
virtual ~Image() {}
virtual ISharedImage* AsSharedImage() { return nullptr; }
ImageFormat GetFormat() { return mFormat; }
void* GetImplData() { return mImplData; }
virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
virtual gfxIntSize GetSize() = 0;
virtual nsIntRect GetPictureRect()
{
return nsIntRect(0, 0, GetSize().width, GetSize().height);
}
ImageBackendData* GetBackendData(LayersBackend aBackend)
{ return mBackendData[aBackend]; }

View File

@ -0,0 +1,129 @@
/* -*- 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/ImageDataSerializer.h"
#include "gfxImageSurface.h"
#include "mozilla/gfx/2D.h"
#include "gfx2DGlue.h"
#include "mozilla/gfx/Tools.h"
namespace mozilla {
namespace layers {
// The Data is layed out as follows:
//
// +-------------------+ -++ --+ <-- ImageDataSerializerBase::mData pointer
// | SurfaceBufferInfo | | |
// +-------------------+ --+ | offset
// | ... | |
// +-------------------+ ------+
// | |
// | data |
// | |
// +-------------------+
// Structure written at the beginning of the data blob containing the image
// (as shown in the figure above). It contains the necessary informations to
// read the image in the blob.
namespace {
struct SurfaceBufferInfo
{
uint32_t width;
uint32_t height;
gfx::SurfaceFormat format;
static uint32_t GetOffset()
{
return gfx::GetAlignedStride<16>(sizeof(SurfaceBufferInfo));
}
};
} // anonymous namespace
static SurfaceBufferInfo* GetBufferInfo(uint8_t* aBuffer)
{
return reinterpret_cast<SurfaceBufferInfo*>(aBuffer);
}
void
ImageDataSerializer::InitializeBufferInfo(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat)
{
SurfaceBufferInfo* info = GetBufferInfo(mData);
info->width = aSize.width;
info->height = aSize.height;
info->format = aFormat;
}
uint32_t
ImageDataSerializer::ComputeMinBufferSize(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat)
{
// Note that at the moment we pack the image data with the minimum possible
// stride, we may decide to change that if we want aligned stride.
gfxIntSize gfxSize = gfxIntSize(aSize.width, aSize.height);
uint32_t bufsize = aSize.height * gfx::BytesPerPixel(aFormat) * aSize.width;
return SurfaceBufferInfo::GetOffset()
+ gfx::GetAlignedStride<16>(bufsize);
}
bool
ImageDataSerializerBase::IsValid() const
{
// XXX - We could use some sanity checks here.
return !!mData;
}
uint8_t*
ImageDataSerializerBase::GetData()
{
MOZ_ASSERT(IsValid());
return mData + SurfaceBufferInfo::GetOffset();
}
gfx::IntSize
ImageDataSerializerBase::GetSize() const
{
MOZ_ASSERT(IsValid());
SurfaceBufferInfo* info = GetBufferInfo(mData);
return gfx::IntSize(info->width, info->height);
}
gfx::SurfaceFormat
ImageDataSerializerBase::GetFormat() const
{
MOZ_ASSERT(IsValid());
return GetBufferInfo(mData)->format;
}
TemporaryRef<gfxImageSurface>
ImageDataSerializerBase::GetAsThebesSurface()
{
MOZ_ASSERT(IsValid());
SurfaceBufferInfo* info = GetBufferInfo(mData);
uint32_t stride = gfxASurface::BytesPerPixel(
gfx::SurfaceFormatToImageFormat(GetFormat())) * info->width;
gfxIntSize size(info->width, info->height);
RefPtr<gfxImageSurface> surf =
new gfxImageSurface(GetData(), size, stride,
gfx::SurfaceFormatToImageFormat(GetFormat()));
return surf.forget();
}
TemporaryRef<gfx::DataSourceSurface>
ImageDataSerializerBase::GetAsSurface()
{
MOZ_ASSERT(IsValid());
SurfaceBufferInfo* info = GetBufferInfo(mData);
gfx::IntSize size(info->width, info->height);
uint32_t stride = gfxASurface::BytesPerPixel(
gfx::SurfaceFormatToImageFormat(GetFormat())) * info->width;
RefPtr<gfx::DataSourceSurface> surf =
gfx::Factory::CreateWrappingDataSourceSurface(GetData(), stride, size, GetFormat());
return surf.forget();
}
} // namespace layers
} // namespace mozilla

View File

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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/. */
#ifndef GFX_LAYERS_BLOBSURFACE_H
#define GFX_LAYERS_BLOBSURFACE_H
#include "mozilla/StandardInteger.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/RefPtr.h"
class gfxImageSurface;
namespace mozilla {
namespace gfx {
class DataSourceSurface;
} // namespace gfx
} // namespace mozilla
namespace mozilla {
namespace layers {
class ImageDataSerializerBase
{
public:
bool IsValid() const;
uint8_t* GetData();
gfx::IntSize GetSize() const;
gfx::SurfaceFormat GetFormat() const;
TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
TemporaryRef<gfxImageSurface> GetAsThebesSurface();
protected:
ImageDataSerializerBase(uint8_t* aData)
: mData(aData) {}
uint8_t* mData;
};
/**
* A facility to serialize an image into a buffer of memory.
* This is intended for use with the IPC code, in order to copy image data
* into shared memory.
* Note that there is a separate serializer class for YCbCr images
* (see YCbCrImageDataSerializer.h).
*/
class MOZ_STACK_CLASS ImageDataSerializer : public ImageDataSerializerBase
{
public:
ImageDataSerializer(uint8_t* aData) : ImageDataSerializerBase(aData) {}
void InitializeBufferInfo(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat);
static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat);
};
/**
* A facility to deserialize image data that has been serialized by an
* ImageDataSerializer.
*/
class MOZ_STACK_CLASS ImageDataDeserializer : public ImageDataSerializerBase
{
public:
ImageDataDeserializer(uint8_t* aData) : ImageDataSerializerBase(aData) {}
};
} // namespace layers
} // namespace mozilla
#endif

View File

@ -215,7 +215,7 @@ AppendToString(nsACString& s, TextureFlags flags,
AppendFlag(ForceSingleTile);
AppendFlag(AllowRepeat);
AppendFlag(NewTile);
AppendFlag(HostRelease);
AppendFlag(TEXTURE_DEALLOCATE_HOST);
#undef AppendFlag
}

View File

@ -4,9 +4,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "yuv_convert.h"
#include "mozilla/gfx/2D.h"
#include "gfx2DGlue.h"
#define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
using namespace mozilla::ipc;
namespace mozilla {
@ -218,6 +220,23 @@ YCbCrImageDataSerializer::CopyData(const uint8_t* aYData,
return true;
}
TemporaryRef<gfx::DataSourceSurface>
YCbCrImageDataDeserializer::ToDataSourceSurface()
{
RefPtr<gfx::DataSourceSurface> result =
gfx::Factory::CreateDataSourceSurface(ToIntSize(GetYSize()), gfx::FORMAT_R8G8B8X8);
gfx::ConvertYCbCrToRGB32(GetYData(), GetCbData(), GetCrData(),
result->GetData(),
0, 0, //pic x and y
GetYSize().width, GetYSize().height,
GetYStride(), GetCbCrStride(),
result->Stride(),
gfx::YV12);
result->MarkDirty();
return result.forget();
}
} // namespace
} // namespace

View File

@ -16,6 +16,10 @@ namespace mozilla {
namespace ipc {
class Shmem;
}
namespace gfx {
class DataSourceSurface;
}
namespace layers {
class Image;
@ -134,6 +138,13 @@ class MOZ_STACK_CLASS YCbCrImageDataDeserializer : public YCbCrImageDataDeserial
{
public:
YCbCrImageDataDeserializer(uint8_t* aData) : YCbCrImageDataDeserializerBase(aData) {}
/**
* Convert the YCbCr data into RGB and return a DataSourceSurface.
* This is a costly operation, so use it only when YCbCr compositing is
* not supported.
*/
TemporaryRef<gfx::DataSourceSurface> ToDataSourceSurface();
};
} // namespace

View File

@ -6,7 +6,8 @@
#ifndef MOZILLA_GFX_BASICCOMPOSITOR_H
#define MOZILLA_GFX_BASICCOMPOSITOR_H
#include "Compositor.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {
@ -32,10 +33,14 @@ public:
virtual ~BasicCompositor();
virtual bool Initialize() MOZ_OVERRIDE { return true; };
virtual void Destroy() MOZ_OVERRIDE;
virtual TemporaryRef<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE { return nullptr; }
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
{
return TextureFactoryIdentifier(LAYERS_BASIC, GetMaxTextureSize());

View File

@ -87,11 +87,11 @@ ClientCanvasLayer::RenderLayer()
}
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
//Append OwnByClient flag for streaming buffer under OOPC case
//Append TEXTURE_DEALLOCATE_CLIENT flag for streaming buffer under OOPC case
if (isCrossProcess && mGLContext) {
GLScreenBuffer* screen = mGLContext->Screen();
if (screen && screen->Stream()) {
flags |= OwnByClient;
flags |= TEXTURE_DEALLOCATE_CLIENT;
}
}
mCanvasClient = CanvasClient::CreateCanvasClient(GetCompositableClientType(),

View File

@ -34,6 +34,10 @@ public:
virtual ~ClientCanvasLayer()
{
MOZ_COUNT_DTOR(ClientCanvasLayer);
if (mCanvasClient) {
mCanvasClient->Detach();
mCanvasClient = nullptr;
}
}
virtual void SetVisibleRegion(const nsIntRegion& aRegion)

View File

@ -64,7 +64,10 @@ public:
void DestroyBackBuffer()
{
mImageClient = nullptr;
if (mImageClient) {
mImageClient->Detach();
mImageClient = nullptr;
}
}
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
@ -112,6 +115,10 @@ ClientImageLayer::RenderLayer()
return;
}
if (mImageClient) {
mImageClient->OnTransaction();
}
if (!mImageClient ||
!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
CompositableType type = GetImageClientType();

View File

@ -323,6 +323,13 @@ ClientLayerManager::ForwardTransaction()
->SetDescriptorFromReply(ots.textureId(), ots.image());
break;
}
case EditReply::TReplyTextureRemoved: {
// XXX - to manage reuse of gralloc buffers, we'll need to add some
// glue code here to find the TextureClient and invoke a callback to
// let the camera know that the gralloc buffer is not used anymore on
// the compositor side and that it can reuse it.
break;
}
default:
NS_RUNTIMEABORT("not reached");

View File

@ -27,6 +27,10 @@ public:
}
virtual ~ClientThebesLayer()
{
if (mContentClient) {
mContentClient->Detach();
mContentClient = nullptr;
}
MOZ_COUNT_DTOR(ClientThebesLayer);
}

View File

@ -8,6 +8,7 @@
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "gfxPlatform.h"
#ifdef XP_WIN
#include "mozilla/layers/TextureD3D11.h"
#include "gfxWindowsPlatform.h"
@ -16,10 +17,20 @@
namespace mozilla {
namespace layers {
CompositableClient::CompositableClient(CompositableForwarder* aForwarder)
: mNextTextureID(1)
, mCompositableChild(nullptr)
, mForwarder(aForwarder)
{
MOZ_COUNT_CTOR(CompositableClient);
}
CompositableClient::~CompositableClient()
{
MOZ_COUNT_DTOR(CompositableClient);
Destroy();
MOZ_ASSERT(mTexturesToRemove.size() == 0, "would leak textures pending fore deletion");
}
LayersBackend
@ -135,5 +146,46 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
return result.forget();
}
TemporaryRef<BufferTextureClient>
CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
{
if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
RefPtr<BufferTextureClient> result = new MemoryTextureClient(this, aFormat);
return result.forget();
}
RefPtr<BufferTextureClient> result = new ShmemTextureClient(this, aFormat);
return result.forget();
}
void
CompositableClient::AddTextureClient(TextureClient* aClient)
{
++mNextTextureID;
// 0 is always an invalid ID
if (mNextTextureID == 0) {
++mNextTextureID;
}
aClient->SetID(mNextTextureID);
mForwarder->AddTexture(this, aClient);
}
void
CompositableClient::RemoveTextureClient(TextureClient* aClient)
{
MOZ_ASSERT(aClient);
mTexturesToRemove.push_back(aClient->GetID());
aClient->SetID(0);
}
void
CompositableClient::OnTransaction()
{
for (unsigned i = 0; i < mTexturesToRemove.size(); ++i) {
mForwarder->RemoveTexture(this, mTexturesToRemove[i]);
}
mTexturesToRemove.clear();
}
} // namespace layers
} // namespace mozilla

View File

@ -16,6 +16,8 @@ namespace layers {
class CompositableChild;
class CompositableClient;
class DeprecatedTextureClient;
class TextureClient;
class BufferTextureClient;
class ImageBridgeChild;
class ShadowableLayer;
class CompositableForwarder;
@ -63,24 +65,20 @@ class SurfaceDescriptor;
class CompositableClient : public RefCounted<CompositableClient>
{
public:
CompositableClient(CompositableForwarder* aForwarder)
: mCompositableChild(nullptr), mForwarder(aForwarder)
{
MOZ_COUNT_CTOR(CompositableClient);
}
CompositableClient(CompositableForwarder* aForwarder);
virtual ~CompositableClient();
virtual TextureInfo GetTextureInfo() const
{
MOZ_CRASH("This method should be overridden");
}
virtual TextureInfo GetTextureInfo() const = 0;
LayersBackend GetCompositorBackendType() const;
TemporaryRef<DeprecatedTextureClient>
CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType);
TemporaryRef<BufferTextureClient>
CreateBufferTextureClient(gfx::SurfaceFormat aFormat);
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
const SurfaceDescriptor& aDescriptor)
{
@ -111,7 +109,31 @@ public:
*/
uint64_t GetAsyncID() const;
/**
* Tells the Compositor to create a TextureHost for this TextureClient.
*/
virtual void AddTextureClient(TextureClient* aClient);
/**
* Tells the Compositor to delete the TextureHost corresponding to this
* TextureClient.
*/
virtual void RemoveTextureClient(TextureClient* aClient);
/**
* A hook for the Compositable to execute whatever it held off for next trasanction.
*/
virtual void OnTransaction();
/**
* A hook for the when the Compositable is detached from it's layer.
*/
virtual void Detach() {}
protected:
// The textures to destroy in the next transaction;
std::vector<uint64_t> mTexturesToRemove;
uint64_t mNextTextureID;
CompositableChild* mCompositableChild;
CompositableForwarder* mForwarder;
};

View File

@ -155,7 +155,7 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
}
DestroyBuffers();
}
mTextureInfo.mTextureFlags = aFlags | HostRelease;
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client");
if (aFlags & BUFFER_COMPONENT_ALPHA) {

View File

@ -390,7 +390,7 @@ private:
void NotifyBufferCreated(ContentType aType, uint32_t aFlags)
{
mTextureInfo.mTextureFlags = aFlags | HostRelease;
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
mContentType = aType;
mForwarder->CreatedIncrementalBuffer(this,

View File

@ -11,6 +11,7 @@
#include "ImageContainer.h" // For PlanarYCbCrImage
#include "mozilla/layers/SharedRGBImage.h"
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
#include "gfxPlatform.h"
#ifdef MOZ_WIDGET_GONK
#include "GrallocImages.h"
@ -26,11 +27,22 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
{
RefPtr<ImageClient> result = nullptr;
switch (aCompositableHostType) {
case COMPOSITABLE_IMAGE:
case BUFFER_IMAGE_SINGLE:
result = new DeprecatedImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_SINGLE);
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
result = new DeprecatedImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_SINGLE);
} else {
result = new ImageClientSingle(aForwarder, aFlags, COMPOSITABLE_IMAGE);
}
break;
case BUFFER_IMAGE_BUFFERED:
result = new DeprecatedImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_BUFFERED);
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
result = new DeprecatedImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_BUFFERED);
} else {
// ImageClientBuffered was a hack for async-video only, and the new textures
// make it so that we don't need to do this hack anymore.
result = new ImageClientSingle(aForwarder, aFlags, COMPOSITABLE_IMAGE);
}
break;
case BUFFER_BRIDGE:
result = new ImageClientBridge(aForwarder, aFlags);
@ -47,6 +59,158 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
return result.forget();
}
ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd,
TextureFlags aFlags,
CompositableType aType)
: ImageClient(aFwd, aType)
, mTextureFlags(aFlags)
{
}
ImageClientBuffered::ImageClientBuffered(CompositableForwarder* aFwd,
TextureFlags aFlags,
CompositableType aType)
: ImageClientSingle(aFwd, aFlags, aType)
{
}
TextureInfo ImageClientSingle::GetTextureInfo() const
{
return TextureInfo(COMPOSITABLE_IMAGE);
}
bool
ImageClientSingle::UpdateImage(ImageContainer* aContainer,
uint32_t aContentFlags)
{
AutoLockImage autoLock(aContainer);
Image *image = autoLock.GetImage();
if (!image) {
return false;
}
if (mLastPaintedImageSerial == image->GetSerial()) {
return true;
}
if (image->AsSharedImage() && image->AsSharedImage()->GetTextureClient()) {
// fast path: no need to allocate and/or copy image data
RefPtr<TextureClient> tex = image->AsSharedImage()->GetTextureClient();
if (mFrontBuffer) {
RemoveTextureClient(mFrontBuffer);
}
mFrontBuffer = tex;
AddTextureClient(tex);
GetForwarder()->UpdatedTexture(this, tex, nullptr);
GetForwarder()->UseTexture(this, tex);
} else if (image->GetFormat() == PLANAR_YCBCR) {
PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image);
const PlanarYCbCrImage::Data* data = ycbcr->GetData();
if (!data) {
return false;
}
if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
RemoveTextureClient(mFrontBuffer);
mFrontBuffer = nullptr;
}
if (!mFrontBuffer) {
mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV);
gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize)) {
mFrontBuffer = nullptr;
return false;
}
AddTextureClient(mFrontBuffer);
}
if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
return false;
}
bool status = mFrontBuffer->AsTextureClientYCbCr()->UpdateYCbCr(*data);
mFrontBuffer->Unlock();
if (status) {
GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
GetForwarder()->UseTexture(this, mFrontBuffer);
} else {
MOZ_ASSERT(false);
return false;
}
} else {
nsRefPtr<gfxASurface> surface = image->GetAsSurface();
MOZ_ASSERT(surface);
if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
RemoveTextureClient(mFrontBuffer);
mFrontBuffer = nullptr;
}
if (!mFrontBuffer) {
gfxASurface::gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface());
mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size);
AddTextureClient(mFrontBuffer);
}
if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
return false;
}
bool status = mFrontBuffer->AsTextureClientSurface()->UpdateSurface(surface);
mFrontBuffer->Unlock();
if (status) {
GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
GetForwarder()->UseTexture(this, mFrontBuffer);
} else {
return false;
}
}
UpdatePictureRect(image->GetPictureRect());
mLastPaintedImageSerial = image->GetSerial();
aContainer->NotifyPaintedImage(image);
return true;
}
bool
ImageClientBuffered::UpdateImage(ImageContainer* aContainer,
uint32_t aContentFlags)
{
RefPtr<TextureClient> temp = mFrontBuffer;
mFrontBuffer = mBackBuffer;
mBackBuffer = temp;
return ImageClientSingle::UpdateImage(aContainer, aContentFlags);
}
void
ImageClientSingle::AddTextureClient(TextureClient* aTexture)
{
aTexture->AddFlags(mTextureFlags);
CompositableClient::AddTextureClient(aTexture);
}
void
ImageClientSingle::Detach()
{
mFrontBuffer = nullptr;
}
void
ImageClientBuffered::Detach()
{
mFrontBuffer = nullptr;
mBackBuffer = nullptr;
}
ImageClient::ImageClient(CompositableForwarder* aFwd, CompositableType aType)
: CompositableClient(aFwd)
@ -232,10 +396,18 @@ ImageClient::CreateImage(const uint32_t *aFormats,
for (uint32_t i = 0; i < aNumFormats; i++) {
switch (aFormats[i]) {
case PLANAR_YCBCR:
img = new DeprecatedSharedPlanarYCbCrImage(GetForwarder());
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
img = new DeprecatedSharedPlanarYCbCrImage(GetForwarder());
} else {
img = new SharedPlanarYCbCrImage(this);
}
return img.forget();
case SHARED_RGB:
img = new DeprecatedSharedRGBImage(GetForwarder());
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
img = new DeprecatedSharedRGBImage(GetForwarder());
} else {
img = new SharedRGBImage(this);
}
return img.forget();
#ifdef MOZ_WIDGET_GONK
case GRALLOC_PLANAR_YCBCR:

View File

@ -44,11 +44,6 @@ public:
*/
virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) = 0;
/**
* Notify the compositor that this image client has been updated
*/
virtual void Updated() = 0;
/**
* The picture rect is the area of the texture which makes up the image. That
* is, the area that should be composited. In texture space.
@ -66,11 +61,55 @@ protected:
nsIntRect mPictureRect;
};
/**
* An image client which uses a single texture client.
*/
class ImageClientSingle : public ImageClient
{
public:
ImageClientSingle(CompositableForwarder* aFwd,
TextureFlags aFlags,
CompositableType aType);
virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags);
virtual void Detach() MOZ_OVERRIDE;
virtual void AddTextureClient(TextureClient* aTexture) MOZ_OVERRIDE;
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE;
protected:
RefPtr<TextureClient> mFrontBuffer;
// Some layers may want to enforce some flags to all their textures
// (like disallowing tiling)
TextureFlags mTextureFlags;
};
/**
* An image client which uses a two texture clients.
*/
class ImageClientBuffered : public ImageClientSingle
{
public:
ImageClientBuffered(CompositableForwarder* aFwd,
TextureFlags aFlags,
CompositableType aType);
virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags);
virtual void Detach() MOZ_OVERRIDE;
protected:
RefPtr<TextureClient> mBackBuffer;
};
/**
* An image client which uses a single texture client, may be single or double
* buffered. (As opposed to using two texture clients for buffering, as in
* ContentClientDoubleBuffered, or using multiple clients for YCbCr or tiled
* images).
*
* XXX - this is deprecated, use ImageClientSingle
*/
class DeprecatedImageClientSingle : public ImageClient
{

View File

@ -17,12 +17,219 @@
#include "gfxReusableSurfaceWrapper.h"
#include "gfxPlatform.h"
#include "mozilla/StandardInteger.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "gfx2DGlue.h"
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
TextureClient::TextureClient(TextureFlags aFlags)
: mID(0)
, mFlags(aFlags)
{}
TextureClient::~TextureClient()
{}
bool
TextureClient::ShouldDeallocateInDestructor() const
{
return IsAllocated() &&
!IsSharedWithCompositor() &&
!(GetFlags() & (TEXTURE_DEALLOCATE_HOST|TEXTURE_DEALLOCATE_CLIENT));
}
bool
ShmemTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
{
if (!IsAllocated() || GetFormat() == gfx::FORMAT_UNKNOWN) {
return false;
}
aDescriptor = SurfaceDescriptorShmem(mShmem, GetFormat());
return true;
}
ISurfaceAllocator*
ShmemTextureClient::GetAllocator() const
{
return mCompositable->GetForwarder();
}
bool
ShmemTextureClient::Allocate(uint32_t aSize)
{
ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
return mAllocated;
}
uint8_t*
ShmemTextureClient::GetBuffer() const
{
if (mAllocated) {
return mShmem.get<uint8_t>();
}
return nullptr;
}
size_t
ShmemTextureClient::GetBufferSize() const
{
return mShmem.Size<uint8_t>();
}
ShmemTextureClient::ShmemTextureClient(CompositableClient* aCompositable,
gfx::SurfaceFormat aFormat)
: BufferTextureClient(aCompositable, aFormat)
, mAllocated(false)
{
MOZ_COUNT_CTOR(ShmemTextureClient);
}
ShmemTextureClient::~ShmemTextureClient()
{
MOZ_COUNT_DTOR(ShmemTextureClient);
if (ShouldDeallocateInDestructor()) {
// if the buffer has never been shared we must deallocate it or ir would
// leak.
mCompositable->GetForwarder()->DeallocShmem(mShmem);
}
}
bool
MemoryTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor)
{
if (!IsAllocated() || GetFormat() == gfx::FORMAT_UNKNOWN) {
return false;
}
aDescriptor = SurfaceDescriptorMemory(reinterpret_cast<uintptr_t>(mBuffer),
GetFormat());
return true;
}
bool
MemoryTextureClient::Allocate(uint32_t aSize)
{
MOZ_ASSERT(!mBuffer);
mBuffer = new uint8_t[aSize];
mBufSize = aSize;
return true;
}
MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat)
: BufferTextureClient(aCompositable, aFormat)
, mBuffer(nullptr)
, mBufSize(0)
{
MOZ_COUNT_CTOR(MemoryTextureClient);
}
MemoryTextureClient::~MemoryTextureClient()
{
MOZ_COUNT_DTOR(MemoryTextureClient);
if (ShouldDeallocateInDestructor()) {
// if the buffer has never been shared we must deallocate it or ir would
// leak.
delete mBuffer;
}
}
BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
gfx::SurfaceFormat aFormat)
: TextureClient()
, mCompositable(aCompositable)
, mFormat(aFormat)
{}
BufferTextureClient::~BufferTextureClient()
{}
bool
BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
{
MOZ_ASSERT(aSurface);
ImageDataSerializer serializer(GetBuffer());
if (!serializer.IsValid()) {
return false;
}
RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
if (!surf) {
return false;
}
nsRefPtr<gfxContext> tmpCtx = new gfxContext(surf.get());
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
tmpCtx->DrawSurface(aSurface, gfxSize(serializer.GetSize().width,
serializer.GetSize().height));
return true;
}
bool
BufferTextureClient::AllocateForSurface(gfx::IntSize aSize)
{
MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This textureClient cannot use YCbCr data");
int bufSize
= ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
if (!Allocate(bufSize)) {
return false;
}
ImageDataSerializer serializer(GetBuffer());
serializer.InitializeBufferInfo(aSize, mFormat);
return true;
}
bool
BufferTextureClient::UpdateYCbCr(const PlanarYCbCrImage::Data& aData)
{
MOZ_ASSERT(mFormat == gfx::FORMAT_YUV, "This textureClient can only use YCbCr data");
MOZ_ASSERT(!IsImmutable());
MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
YCbCrImageDataSerializer serializer(GetBuffer());
MOZ_ASSERT(serializer.IsValid());
if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
aData.mYSize, aData.mYStride,
aData.mCbCrSize, aData.mCbCrStride,
aData.mYSkip, aData.mCbSkip)) {
NS_WARNING("Failed to copy image data!");
return false;
}
return true;
}
bool
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize)
{
size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
aCbCrSize);
if (!Allocate(bufSize)) {
return false;
}
YCbCrImageDataSerializer serializer(GetBuffer());
serializer.InitializeBufferInfo(aYSize,
aCbCrSize);
return true;
}
DeprecatedTextureClient::DeprecatedTextureClient(CompositableForwarder* aForwarder,
const TextureInfo& aTextureInfo)
: mForwarder(aForwarder)
@ -54,7 +261,7 @@ DeprecatedTextureClientShmem::ReleaseResources()
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
}
if (mTextureInfo.mTextureFlags & HostRelease) {
if (mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_HOST) {
mDescriptor = SurfaceDescriptor();
return;
}
@ -154,6 +361,14 @@ DeprecatedTextureClientShmem::LockImageSurface()
return mSurfaceAsImage.get();
}
DeprecatedTextureClientTile::DeprecatedTextureClientTile(const DeprecatedTextureClientTile& aOther)
: DeprecatedTextureClient(aOther.mForwarder, aOther.mTextureInfo)
, mSurface(aOther.mSurface)
{}
DeprecatedTextureClientTile::~DeprecatedTextureClientTile()
{}
void
DeprecatedTextureClientShmemYCbCr::ReleaseResources()
{
@ -193,14 +408,6 @@ DeprecatedTextureClientShmemYCbCr::EnsureAllocated(gfx::IntSize aSize,
}
DeprecatedTextureClientTile::DeprecatedTextureClientTile(const DeprecatedTextureClientTile& aOther)
: DeprecatedTextureClient(aOther.mForwarder, aOther.mTextureInfo)
, mSurface(aOther.mSurface)
{}
DeprecatedTextureClientTile::~DeprecatedTextureClientTile()
{}
DeprecatedTextureClientTile::DeprecatedTextureClientTile(CompositableForwarder* aForwarder,
const TextureInfo& aTextureInfo)
: DeprecatedTextureClient(aForwarder, aTextureInfo)
@ -233,6 +440,10 @@ DeprecatedTextureClientTile::LockImageSurface()
return writableSurface;
}
// XXX - All the code below can be removed as soon as we remove
// DeprecatedImageClientSingle (which has already been ported to the new
// textures).
bool AutoLockShmemClient::Update(Image* aImage,
uint32_t aContentFlags,
gfxASurface *aSurface)
@ -344,5 +555,6 @@ bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage
return true;
}
}
}

View File

@ -10,6 +10,7 @@
#include "gfxASurface.h"
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo
#include "mozilla/RefPtr.h"
#include "ImageContainer.h" // for PlanarYCbCrImage::Data
class gfxReusableSurfaceWrapper;
@ -25,6 +26,267 @@ class ContentClient;
class PlanarYCbCrImage;
class Image;
class CompositableForwarder;
class ISurfaceAllocator;
class CompositableClient;
/**
* TextureClient is the abstraction that allows us to share data between the
* content and the compositor side.
* TextureClient can also provide with some more more "producer" facing APIs
* such as TextureClientSurface and TextureClientYCbCr, that can be queried
* using AsTextureCLientSurface(), etc.
*/
/**
* Interface for TextureClients that can be updated using a gfxASurface.
*/
class TextureClientSurface
{
public:
virtual bool UpdateSurface(gfxASurface* aSurface) = 0;
virtual bool AllocateForSurface(gfx::IntSize aSize) = 0;
};
/**
* Interface for TextureClients that can be updated using YCbCr data.
*/
class TextureClientYCbCr
{
public:
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) = 0;
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) = 0;
};
/**
* TextureClient is a thin abstraction over texture data that need to be shared
* between the content process and the compositor process. It is the
* content-side half of a TextureClient/TextureHost pair. A corresponding
* TextureHost lives on the compositor-side.
*
* TextureClient's primary purpose is to present texture data in a way that is
* understood by the IPC system. There are two ways to use it:
* - Use it to serialize image data that is not IPC-friendly (most likely
* involving a copy into shared memory)
* - preallocate it and paint directly into it, which avoids copy but requires
* the painting code to be aware of TextureClient (or at least the underlying
* shared memory)
*
* There is always one and only one TextureClient per TextureHost, and the
* TextureClient/Host pair only owns one buffer of image data through its
* lifetime. This means that to the lifetime of the underlying shared data
* matches the lifetime of the TextureClient/Host pair. It also means
* TextureClient/Host do not implement double buffering, which is the
* responsibility of the compositable (which would use two Texture pairs).
* In order to send several different buffers to the compositor side, use
* several TextureClients.
*/
class TextureClient : public RefCounted<TextureClient>
{
public:
TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
virtual ~TextureClient();
virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; }
virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
virtual void MarkUnused() {}
virtual bool Lock(OpenMode aMode)
{
return true;
}
virtual void Unlock() {}
void SetID(uint64_t aID)
{
MOZ_ASSERT(mID == 0 || aID == 0);
mID = aID;
}
uint64_t GetID() const
{
return mID;
}
void SetNextSibling(TextureClient* aNext)
{
mNextSibling = aNext;
}
TextureClient* GetNextSibling()
{
return mNextSibling;
}
virtual bool IsAllocated() const = 0;
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
void SetFlags(TextureFlags aFlags)
{
MOZ_ASSERT(!IsSharedWithCompositor());
mFlags = aFlags;
}
void AddFlags(TextureFlags aFlags)
{
MOZ_ASSERT(!IsSharedWithCompositor());
// make sure we don't deallocate on both client and host;
MOZ_ASSERT(!(aFlags & TEXTURE_DEALLOCATE_CLIENT && aFlags & TEXTURE_DEALLOCATE_HOST));
if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
mFlags &= ~TEXTURE_DEALLOCATE_HOST;
} else if (aFlags & TEXTURE_DEALLOCATE_HOST) {
mFlags &= ~TEXTURE_DEALLOCATE_CLIENT;
}
mFlags |= aFlags;
}
void RemoveFlags(TextureFlags aFlags)
{
MOZ_ASSERT(!IsSharedWithCompositor());
mFlags &= (~aFlags);
}
TextureFlags GetFlags() const { return mFlags; }
/**
* After being shared ith the compositor side, an immutable texture is never
* modified, it can only be read. It is safe to not Lock/Unlock immutable
* textures.
*/
bool IsImmutable() const { return mFlags & TEXTURE_IMMUTABLE; }
void MarkImmutable() { AddFlags(TEXTURE_IMMUTABLE); }
bool IsSharedWithCompositor() const { return GetID() != 0; }
bool ShouldDeallocateInDestructor() const;
protected:
uint64_t mID;
RefPtr<TextureClient> mNextSibling;
TextureFlags mFlags;
};
/**
* TextureClient that wraps a random access buffer such as a Shmem or raw memory.
* This class must be inherited to implement the memory allocation and access bits.
* (see ShmemTextureClient and MemoryTextureClient)
*/
class BufferTextureClient : public TextureClient
, public TextureClientSurface
, TextureClientYCbCr
{
public:
BufferTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
virtual ~BufferTextureClient();
virtual bool IsAllocated() const = 0;
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
virtual bool Allocate(uint32_t aSize) = 0;
virtual uint8_t* GetBuffer() const = 0;
virtual size_t GetBufferSize() const = 0;
// TextureClientSurface
virtual TextureClientSurface* AsTextureClientSurface() MOZ_OVERRIDE { return this; }
virtual bool UpdateSurface(gfxASurface* aSurface) MOZ_OVERRIDE;
virtual bool AllocateForSurface(gfx::IntSize aSize) MOZ_OVERRIDE;
// TextureClientYCbCr
virtual TextureClientYCbCr* AsTextureClientYCbCr() MOZ_OVERRIDE { return this; }
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) MOZ_OVERRIDE;
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) MOZ_OVERRIDE;
gfx::SurfaceFormat GetFormat() const { return mFormat; }
protected:
CompositableClient* mCompositable;
gfx::SurfaceFormat mFormat;
};
/**
* TextureClient that wraps shared memory.
* the corresponding texture on the host side is ShmemTextureHost.
*/
class ShmemTextureClient : public BufferTextureClient
{
public:
ShmemTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
~ShmemTextureClient();
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() const MOZ_OVERRIDE;
virtual size_t GetBufferSize() const MOZ_OVERRIDE;
virtual bool IsAllocated() const MOZ_OVERRIDE { return mAllocated; }
ISurfaceAllocator* GetAllocator() const;
ipc::Shmem& GetShmem() { return mShmem; }
protected:
ipc::Shmem mShmem;
ISurfaceAllocator* mAllocator;
bool mAllocated;
};
/**
* TextureClient that wraps raw memory.
* The corresponding texture on the host side is MemoryTextureHost.
* Can obviously not be used in a cross process setup.
*/
class MemoryTextureClient : public BufferTextureClient
{
public:
MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
~MemoryTextureClient();
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() const MOZ_OVERRIDE { return mBuffer; }
virtual size_t GetBufferSize() const MOZ_OVERRIDE { return mBufSize; }
virtual bool IsAllocated() const MOZ_OVERRIDE { return mBuffer != nullptr; }
protected:
uint8_t* mBuffer;
size_t mBufSize;
};
struct TextureClientAutoUnlock
{
TextureClient* mTexture;
TextureClientAutoUnlock(TextureClient* aTexture)
: mTexture(aTexture) {}
~TextureClientAutoUnlock()
{
mTexture->Unlock();
}
};
/**
* XXX - This class is deprecated, will be removed soon.
@ -185,6 +447,7 @@ private:
friend class CompositingFactory;
};
// XXX - this class can be removed as soon as we remove DeprecatedImageClientSingle
class DeprecatedTextureClientShmemYCbCr : public DeprecatedTextureClient
{
public:
@ -237,6 +500,7 @@ private:
/**
* Base class for AutoLock*Client.
* handles lock/unlock
* XXX - this can be removed as soon as we remove DeprecatedImageClientSingle
*/
class AutoLockDeprecatedTextureClient
{
@ -263,6 +527,7 @@ protected:
/**
* Writes the content of a PlanarYCbCrImage into a SurfaceDescriptor.
* XXX - this can be removed as soon as we remove DeprecatedImageClientSingle
*/
class AutoLockYCbCrClient : public AutoLockDeprecatedTextureClient
{
@ -275,6 +540,7 @@ protected:
/**
* Writes the content of a gfxASurface into a SurfaceDescriptor.
* XXX - this can be removed as soon as we remove DeprecatedImageClientSingle
*/
class AutoLockShmemClient : public AutoLockDeprecatedTextureClient
{

View File

@ -34,7 +34,7 @@ CanvasLayerComposite::~CanvasLayerComposite()
}
void CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
mImageHost = static_cast<ImageHost*>(aHost);
mImageHost = aHost;
}
Layer*

View File

@ -63,7 +63,7 @@ protected:
#endif
private:
RefPtr<ImageHost> mImageHost;
RefPtr<CompositableHost> mImageHost;
};
} /* layers */

View File

@ -9,10 +9,81 @@
#include "TiledContentHost.h"
#include "Effects.h"
#include "mozilla/layers/CompositableTransactionParent.h"
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {
CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
: mTextureInfo(aTextureInfo)
, mCompositor(nullptr)
, mLayer(nullptr)
{
MOZ_COUNT_CTOR(CompositableHost);
}
CompositableHost::~CompositableHost()
{
MOZ_COUNT_DTOR(CompositableHost);
RefPtr<TextureHost> it = mFirstTexture;
while (it) {
if (it->GetFlags() & TEXTURE_DEALLOCATE_HOST) {
it->DeallocateSharedData();
}
it = it->GetNextSibling();
}
}
void
CompositableHost::AddTextureHost(TextureHost* aTexture)
{
MOZ_ASSERT(aTexture);
MOZ_ASSERT(GetTextureHost(aTexture->GetID()) == nullptr,
"A texture is already present with this ID");
RefPtr<TextureHost> second = mFirstTexture;
mFirstTexture = aTexture;
aTexture->SetNextSibling(second);
}
void
CompositableHost::RemoveTextureHost(uint64_t aTextureID)
{
RefPtr<TextureHost> it = mFirstTexture;
while (it) {
if (it->GetNextSibling() &&
it->GetNextSibling()->GetID() == aTextureID) {
it->SetNextSibling(it->GetNextSibling()->GetNextSibling());
}
it = it->GetNextSibling();
}
}
TextureHost*
CompositableHost::GetTextureHost(uint64_t aTextureID)
{
RefPtr<TextureHost> it = mFirstTexture;
while (it) {
if (it->GetID() == aTextureID) {
return it;
}
it = it->GetNextSibling();
}
return nullptr;
}
void
CompositableHost::SetCompositor(Compositor* aCompositor)
{
mCompositor = aCompositor;
RefPtr<TextureHost> it = mFirstTexture;
while (!!it) {
it->SetCompositor(aCompositor);
it = it->GetNextSibling();
}
}
bool
CompositableHost::Update(const SurfaceDescriptor& aImage,
SurfaceDescriptor* aResult)
@ -53,6 +124,9 @@ CompositableHost::Create(const TextureInfo& aTextureInfo)
{
RefPtr<CompositableHost> result;
switch (aTextureInfo.mCompositableType) {
case COMPOSITABLE_IMAGE:
result = new ImageHost(aTextureInfo);
return result;
case BUFFER_IMAGE_BUFFERED:
result = new DeprecatedImageHostBuffered(aTextureInfo);
return result;
@ -89,6 +163,19 @@ CompositableHost::DumpDeprecatedTextureHost(FILE* aFile, DeprecatedTextureHost*
surf->DumpAsDataURL(aFile ? aFile : stderr);
}
void
CompositableHost::DumpTextureHost(FILE* aFile, TextureHost* aTexture)
{
if (!aTexture) {
return;
}
nsRefPtr<gfxImageSurface> surf = aTexture->GetAsSurface();
if (!surf) {
return;
}
surf->DumpAsDataURL(aFile ? aFile : stderr);
}
void
CompositableParent::ActorDestroy(ActorDestroyReason why)
{

View File

@ -29,6 +29,7 @@ struct TiledLayerProperties
class Layer;
class DeprecatedTextureHost;
class TextureHost;
class SurfaceDescriptor;
/**
@ -48,27 +49,16 @@ class SurfaceDescriptor;
class CompositableHost : public RefCounted<CompositableHost>
{
public:
CompositableHost(const TextureInfo& aTextureInfo)
: mTextureInfo(aTextureInfo)
, mCompositor(nullptr)
, mLayer(nullptr)
{
MOZ_COUNT_CTOR(CompositableHost);
}
CompositableHost(const TextureInfo& aTextureInfo);
virtual ~CompositableHost()
{
MOZ_COUNT_DTOR(CompositableHost);
}
virtual ~CompositableHost();
static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
virtual CompositableType GetType() = 0;
virtual void SetCompositor(Compositor* aCompositor)
{
mCompositor = aCompositor;
}
// If base class overrides, it should still call the parent implementation
virtual void SetCompositor(Compositor* aCompositor);
// composite the contents of this buffer host to the compositor's surface
virtual void Composite(EffectChain& aEffectChain,
@ -139,7 +129,10 @@ public:
virtual void EnsureDeprecatedTextureHost(TextureIdentifier aTextureId,
const SurfaceDescriptor& aSurface,
ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo) = 0;
const TextureInfo& aTextureInfo)
{
MOZ_ASSERT(false, "should be implemented or not used");
}
/**
* Ensure that a suitable texture host exists in this compsitable.
@ -159,6 +152,11 @@ public:
virtual DeprecatedTextureHost* GetDeprecatedTextureHost() { return nullptr; }
/**
* Returns the front buffer.
*/
virtual TextureHost* GetTextureHost() { return nullptr; }
virtual LayerRenderState GetRenderState() = 0;
virtual void SetPictureRect(const nsIntRect& aPictureRect)
@ -199,6 +197,7 @@ public:
const char* aPrefix="",
bool aDumpHtml=false) { }
static void DumpDeprecatedTextureHost(FILE* aFile, DeprecatedTextureHost* aTexture);
static void DumpTextureHost(FILE* aFile, TextureHost* aTexture);
#ifdef MOZ_DUMP_PAINTING
virtual already_AddRefed<gfxImageSurface> GetAsSurface() { return nullptr; }
@ -208,10 +207,16 @@ public:
virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
#endif
void AddTextureHost(TextureHost* aTexture);
virtual void UseTextureHost(TextureHost* aTexture) {}
void RemoveTextureHost(uint64_t aTextureID);
TextureHost* GetTextureHost(uint64_t aTextureID);
protected:
TextureInfo mTextureInfo;
Compositor* mCompositor;
Layer* mLayer;
RefPtr<TextureHost> mFirstTexture;
};
class CompositableParentManager;

View File

@ -758,5 +758,26 @@ ContentHostDoubleBuffered::Dump(FILE* aFile,
}
LayerRenderState
ContentHostBase::GetRenderState()
{
LayerRenderState result = mDeprecatedTextureHost->GetRenderState();
if (mBufferRotation != nsIntPoint()) {
result.mFlags |= LAYER_RENDER_STATE_BUFFER_ROTATION;
}
result.SetOffset(GetOriginOffset());
return result;
}
#ifdef MOZ_DUMP_PAINTING
already_AddRefed<gfxImageSurface>
ContentHostBase::GetAsSurface()
{
return mDeprecatedTextureHost->GetAsSurface();
}
#endif
} // namespace
} // namespace

View File

@ -77,24 +77,12 @@ public:
return PaintState();
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE
{
LayerRenderState result = mDeprecatedTextureHost->GetRenderState();
if (mBufferRotation != nsIntPoint()) {
result.mFlags |= LAYER_RENDER_STATE_BUFFER_ROTATION;
}
result.SetOffset(GetOriginOffset());
return result;
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
#ifdef MOZ_DUMP_PAINTING
virtual already_AddRefed<gfxImageSurface> GetAsSurface()
{
return mDeprecatedTextureHost->GetAsSurface();
}
virtual already_AddRefed<gfxImageSurface> GetAsSurface();
#endif
virtual void Dump(FILE* aFile=nullptr,

View File

@ -16,6 +16,149 @@ using namespace gfx;
namespace layers {
ImageHost::ImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
, mFrontBuffer(nullptr)
, mHasPictureRect(false)
{}
ImageHost::~ImageHost() {}
void
ImageHost::UseTextureHost(TextureHost* aTexture)
{
mFrontBuffer = aTexture;
}
TextureHost*
ImageHost::GetTextureHost()
{
return mFrontBuffer;
}
void
ImageHost::Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Point& aOffset,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion,
TiledLayerProperties* aLayerProperties)
{
if (!GetCompositor()) {
// should only happen when a tab is dragged to another window and
// async-video is still sending frames but we haven't attached the
// set the new compositor yet.
return;
}
if (!mFrontBuffer) {
return;
}
if (!mFrontBuffer->Lock()) {
NS_WARNING("failed to lock front buffer");
return;
}
RefPtr<NewTextureSource> source = mFrontBuffer->GetTextureSources();
if (!source) {
return;
}
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
source,
aFilter);
aEffectChain.mPrimaryEffect = effect;
TileIterator* it = source->AsTileIterator();
if (it) {
it->BeginTileIteration();
do {
nsIntRect tileRect = it->GetTileRect();
gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
aOpacity, aTransform, aOffset);
GetCompositor()->DrawDiagnostics(gfx::Color(0.5,0.0,0.0,1.0),
rect, aClipRect, aTransform, aOffset);
} while (it->NextTile());
it->EndTileIteration();
} else {
IntSize textureSize = source->GetSize();
gfx::Rect rect(0, 0,
mPictureRect.width,
mPictureRect.height);
if (mHasPictureRect) {
effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width,
Float(mPictureRect.y) / textureSize.height,
Float(mPictureRect.width) / textureSize.width,
Float(mPictureRect.height) / textureSize.height);
} else {
effect->mTextureCoords = Rect(0, 0, 1, 1);
rect = gfx::Rect(0, 0, textureSize.width, textureSize.height);
}
if (mFrontBuffer->GetFlags() & NeedsYFlip) {
effect->mTextureCoords.y = effect->mTextureCoords.YMost();
effect->mTextureCoords.height = -effect->mTextureCoords.height;
}
GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
aOpacity, aTransform, aOffset);
GetCompositor()->DrawDiagnostics(gfx::Color(1.0,0.1,0.1,1.0),
rect, aClipRect, aTransform, aOffset);
}
mFrontBuffer->Unlock();
}
#ifdef MOZ_LAYERS_HAVE_LOG
void
ImageHost::PrintInfo(nsACString& aTo, const char* aPrefix)
{
aTo += aPrefix;
aTo += nsPrintfCString("ImageHost (0x%p)", this);
AppendToString(aTo, mPictureRect, " [picture-rect=", "]");
if (mFrontBuffer) {
nsAutoCString pfx(aPrefix);
pfx += " ";
aTo += "\n";
mFrontBuffer->PrintInfo(aTo, pfx.get());
}
}
#endif
void
ImageHost::Dump(FILE* aFile,
const char* aPrefix,
bool aDumpHtml)
{
if (!aFile) {
aFile = stderr;
}
if (mFrontBuffer) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, aDumpHtml ? "<ul><li>TextureHost: "
: "TextureHost: ");
DumpTextureHost(aFile, mFrontBuffer);
fprintf(aFile, aDumpHtml ? " </li></ul> " : " ");
}
}
LayerRenderState
ImageHost::GetRenderState()
{
if (mFrontBuffer) {
return mFrontBuffer->GetRenderState();
}
return LayerRenderState();
}
#ifdef MOZ_DUMP_PAINTING
already_AddRefed<gfxImageSurface>
ImageHost::GetAsSurface()
{
return mFrontBuffer->GetAsSurface();
}
#endif
void
DeprecatedImageHostSingle::SetCompositor(Compositor* aCompositor) {
CompositableHost::SetCompositor(aCompositor);
@ -60,6 +203,15 @@ DeprecatedImageHostSingle::MakeDeprecatedTextureHost(TextureIdentifier aTextureI
}
}
LayerRenderState
DeprecatedImageHostSingle::GetRenderState()
{
if (mDeprecatedTextureHost) {
return mDeprecatedTextureHost->GetRenderState();
}
return LayerRenderState();
}
void
DeprecatedImageHostSingle::Composite(EffectChain& aEffectChain,
float aOpacity,
@ -197,5 +349,14 @@ DeprecatedImageHostSingle::Dump(FILE* aFile,
}
}
#ifdef MOZ_DUMP_PAINTING
already_AddRefed<gfxImageSurface>
DeprecatedImageHostSingle::GetAsSurface()
{
return mDeprecatedTextureHost->GetAsSurface();
}
#endif
}
}

View File

@ -12,36 +12,65 @@
namespace mozilla {
namespace layers {
class TextureHost;
/**
* Used for compositing Image and Canvas layers, matched on the content-side
* by an ImageClient or CanvasClient.
*
* ImageHosts support Update., not UpdateThebes().
* ImageHost. Works with ImageClientSingle and ImageClientBuffered
*/
class ImageHost : public CompositableHost
{
public:
DeprecatedTextureHost* GetDeprecatedTextureHost() MOZ_OVERRIDE { return nullptr; }
ImageHost(const TextureInfo& aTextureInfo);
~ImageHost();
virtual CompositableType GetType() { return mTextureInfo.mCompositableType; }
virtual void Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Point& aOffset,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr,
TiledLayerProperties* aLayerProperties = nullptr);
virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
virtual TextureHost* GetTextureHost() MOZ_OVERRIDE;
virtual void SetPictureRect(const nsIntRect& aPictureRect) MOZ_OVERRIDE
{
mPictureRect = aPictureRect;
mHasPictureRect = true;
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
virtual void Dump(FILE* aFile=NULL,
const char* aPrefix="",
bool aDumpHtml=false) MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
#endif
#ifdef MOZ_DUMP_PAINTING
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
#endif
protected:
ImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
{
MOZ_COUNT_CTOR(ImageHost);
}
~ImageHost()
{
MOZ_COUNT_DTOR(ImageHost);
}
RefPtr<TextureHost> mFrontBuffer;
nsIntRect mPictureRect;
bool mHasPictureRect;
};
// ImageHost with a single DeprecatedTextureHost
class DeprecatedImageHostSingle : public ImageHost
class DeprecatedImageHostSingle : public CompositableHost
{
public:
DeprecatedImageHostSingle(const TextureInfo& aTextureInfo)
: ImageHost(aTextureInfo)
: CompositableHost(aTextureInfo)
, mDeprecatedTextureHost(nullptr)
, mHasPictureRect(false)
{}
@ -67,7 +96,7 @@ public:
virtual bool Update(const SurfaceDescriptor& aImage,
SurfaceDescriptor* aResult = nullptr) MOZ_OVERRIDE
{
return ImageHost::Update(aImage, aResult);
return CompositableHost::Update(aImage, aResult);
}
virtual void SetPictureRect(const nsIntRect& aPictureRect) MOZ_OVERRIDE
@ -76,13 +105,7 @@ public:
mHasPictureRect = true;
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE
{
if (mDeprecatedTextureHost) {
return mDeprecatedTextureHost->GetRenderState();
}
return LayerRenderState();
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
@ -95,10 +118,7 @@ public:
#endif
#ifdef MOZ_DUMP_PAINTING
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
{
return mDeprecatedTextureHost->GetAsSurface();
}
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
#endif
protected:

View File

@ -42,7 +42,7 @@ ImageLayerComposite::~ImageLayerComposite()
void
ImageLayerComposite::SetCompositableHost(CompositableHost* aHost)
{
mImageHost = static_cast<ImageHost*>(aHost);
mImageHost = aHost;
}
void
@ -105,8 +105,11 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
// Snap image edges to pixel boundaries
gfxRect sourceRect(0, 0, 0, 0);
if (mImageHost && mImageHost->GetDeprecatedTextureHost()) {
IntSize size = mImageHost->GetDeprecatedTextureHost()->GetSize();
if (mImageHost &&
(mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) {
IntSize size =
mImageHost->GetTextureHost() ? mImageHost->GetTextureHost()->GetSize()
: mImageHost->GetDeprecatedTextureHost()->GetSize();
sourceRect.SizeTo(size.width, size.height);
if (mScaleMode != SCALE_NONE &&
sourceRect.width != 0.0 && sourceRect.height != 0.0) {

View File

@ -55,7 +55,7 @@ protected:
#endif
private:
RefPtr<ImageHost> mImageHost;
RefPtr<CompositableHost> mImageHost;
};
} /* layers */

View File

@ -7,6 +7,13 @@
#include "mozilla/layers/LayersSurfaces.h"
#include "LayersLogging.h"
#include "nsPrintfCString.h"
#include "mozilla/ipc/Shmem.h"
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "gfx2DGlue.h"
#include "mozilla/gfx/2D.h"
namespace mozilla {
namespace layers {
@ -63,12 +70,75 @@ DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptorType aDescri
}
}
// implemented in TextureOGL.cpp
TemporaryRef<TextureHost> CreateTextureHostOGL(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
// static
TemporaryRef<TextureHost>
TextureHost::Create(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags)
{
switch (Compositor::GetBackend()) {
case LAYERS_OPENGL:
return CreateTextureHostOGL(aID, aDesc, aDeallocator, aFlags);
case LAYERS_BASIC:
return CreateBackendIndependentTextureHost(aID,
aDesc,
aDeallocator,
aFlags);
#ifdef XP_WIN
case LAYERS_D3D11:
case LAYERS_D3D9:
// XXX - not implemented yet
#endif
default:
MOZ_CRASH("Couldn't create texture host");
return nullptr;
}
}
TemporaryRef<TextureHost>
CreateBackendIndependentTextureHost(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorShmem: {
const SurfaceDescriptorShmem& descriptor = aDesc.get_SurfaceDescriptorShmem();
result = new ShmemTextureHost(aID,
descriptor.data(),
descriptor.format(),
aDeallocator,
aFlags);
break;
}
case SurfaceDescriptor::TSurfaceDescriptorMemory: {
const SurfaceDescriptorMemory& descriptor = aDesc.get_SurfaceDescriptorMemory();
result = new MemoryTextureHost(aID,
reinterpret_cast<uint8_t*>(descriptor.data()),
descriptor.format(),
aFlags);
break;
}
default: {
NS_WARNING("No backend independent TextureHost for this descriptor type");
}
}
return result;
}
DeprecatedTextureHost::DeprecatedTextureHost()
: mFlags(0)
, mBuffer(nullptr)
, mFormat(gfx::FORMAT_UNKNOWN)
, mDeAllocator(nullptr)
, mFormat(gfx::FORMAT_UNKNOWN)
{
MOZ_COUNT_CTOR(DeprecatedTextureHost);
}
@ -76,7 +146,7 @@ DeprecatedTextureHost::DeprecatedTextureHost()
DeprecatedTextureHost::~DeprecatedTextureHost()
{
if (mBuffer) {
if (!(mFlags & OwnByClient)) {
if (!(mFlags & TEXTURE_DEALLOCATE_CLIENT)) {
if (mDeAllocator) {
mDeAllocator->DestroySharedSurface(mBuffer);
} else {
@ -130,5 +200,272 @@ DeprecatedTextureHost::PrintInfo(nsACString& aTo, const char* aPrefix)
#endif // MOZ_LAYERS_HAVE_LOG
BufferTextureHost::BufferTextureHost(uint64_t aID,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
: TextureHost(aID, aFlags)
, mCompositor(nullptr)
, mFormat(aFormat)
, mUpdateSerial(1)
, mLocked(false)
, mPartialUpdate(false)
{}
BufferTextureHost::~BufferTextureHost()
{}
void
BufferTextureHost::Updated(const nsIntRegion* aRegion)
{
++mUpdateSerial;
if (aRegion) {
mPartialUpdate = true;
mMaybeUpdatedRegion = *aRegion;
} else {
mPartialUpdate = false;
}
}
void
BufferTextureHost::SetCompositor(Compositor* aCompositor)
{
if (mCompositor == aCompositor) {
return;
}
DeallocateDeviceData();
mCompositor = aCompositor;
}
void
BufferTextureHost::DeallocateDeviceData()
{
RefPtr<NewTextureSource> it = mFirstSource;
while (it) {
it->DeallocateDeviceData();
it = it->GetNextSibling();
}
}
bool
BufferTextureHost::Lock()
{
mLocked = true;
return true;
}
void
BufferTextureHost::Unlock()
{
mLocked = false;
}
NewTextureSource*
BufferTextureHost::GetTextureSources()
{
MOZ_ASSERT(mLocked, "should never be called while not locked");
if (!mFirstSource || mUpdateSerial != mFirstSource->GetUpdateSerial()) {
if (!Upload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr)) {
return nullptr;
}
mFirstSource->SetUpdateSerial(mUpdateSerial);
}
return mFirstSource;
}
gfx::SurfaceFormat
BufferTextureHost::GetFormat() const
{
// mFormat is the format of the data that we share with the content process.
// GetFormat, on the other hand, expects the format that we present to the
// Compositor (it is used to choose the effect type).
// if the compositor does not support YCbCr effects, we give it a RGBX texture
// instead (see BufferTextureHost::Upload)
if (mFormat == gfx::FORMAT_YUV &&
mCompositor &&
!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
return gfx::FORMAT_R8G8B8X8;
}
return mFormat;
}
bool
BufferTextureHost::Upload(nsIntRegion *aRegion)
{
if (mFormat == gfx::FORMAT_UNKNOWN) {
NS_WARNING("BufferTextureHost: unsupported format!");
return false;
} else if (mFormat == gfx::FORMAT_YUV) {
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
MOZ_ASSERT(yuvDeserializer.IsValid());
if (!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
RefPtr<gfx::DataSourceSurface> surf = yuvDeserializer.ToDataSourceSurface();
if (!mFirstSource) {
mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
}
mFirstSource->Update(surf, mFlags, aRegion);
return true;
}
RefPtr<DataTextureSource> srcY;
RefPtr<DataTextureSource> srcU;
RefPtr<DataTextureSource> srcV;
if (!mFirstSource) {
srcY = mCompositor->CreateDataTextureSource(mFlags);
srcU = mCompositor->CreateDataTextureSource(mFlags);
srcV = mCompositor->CreateDataTextureSource(mFlags);
mFirstSource = srcY;
srcY->SetNextSibling(srcU);
srcU->SetNextSibling(srcV);
} else {
// mFormat never changes so if this was created as a YCbCr host and already
// contains a source it should already have 3 sources.
// BufferTextureHost only uses DataTextureSources so it is safe to assume
// all 3 sources are DataTextureSource.
MOZ_ASSERT(mFirstSource->GetNextSibling());
MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling());
srcY = mFirstSource;
srcU = mFirstSource->GetNextSibling()->AsDataTextureSource();
srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
}
RefPtr<gfx::DataSourceSurface> tempY =
gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetYData(),
yuvDeserializer.GetYStride(),
gfx::ToIntSize(yuvDeserializer.GetYSize()),
gfx::FORMAT_A8);
RefPtr<gfx::DataSourceSurface> tempCb =
gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCbData(),
yuvDeserializer.GetCbCrStride(),
gfx::ToIntSize(yuvDeserializer.GetCbCrSize()),
gfx::FORMAT_A8);
RefPtr<gfx::DataSourceSurface> tempCr =
gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCrData(),
yuvDeserializer.GetCbCrStride(),
gfx::ToIntSize(yuvDeserializer.GetCbCrSize()),
gfx::FORMAT_A8);
// We don't support partial updates for Y U V textures
NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
if (!srcY->Update(tempY, mFlags) ||
!srcU->Update(tempCb, mFlags) ||
!srcV->Update(tempCr, mFlags)) {
NS_WARNING("failed to update the DataTextureSource");
return false;
}
} else {
// non-YCbCr case
if (!mFirstSource) {
mFirstSource = mCompositor->CreateDataTextureSource();
}
ImageDataDeserializer deserializer(GetBuffer());
if (!deserializer.IsValid()) {
NS_WARNING("failed to open shmem surface");
return false;
}
RefPtr<gfx::DataSourceSurface> surf = deserializer.GetAsSurface();
if (!mFirstSource->Update(surf.get(), mFlags, aRegion)) {
NS_WARNING("failed to update the DataTextureSource");
return false;
}
}
return true;
}
already_AddRefed<gfxImageSurface>
BufferTextureHost::GetAsSurface()
{
nsRefPtr<gfxImageSurface> result;
if (mFormat == gfx::FORMAT_UNKNOWN) {
NS_WARNING("BufferTextureHost: unsupported format!");
return nullptr;
} else if (mFormat == gfx::FORMAT_YUV) {
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
if (!yuvDeserializer.IsValid()) {
return nullptr;
}
result = new gfxImageSurface(yuvDeserializer.GetYData(),
yuvDeserializer.GetYSize(),
yuvDeserializer.GetYStride(),
gfxASurface::ImageFormatA8);
} else {
ImageDataDeserializer deserializer(GetBuffer());
if (!deserializer.IsValid()) {
return nullptr;
}
RefPtr<gfxImageSurface> surf = deserializer.GetAsThebesSurface();
result = surf.get();
}
return result.forget();
}
ShmemTextureHost::ShmemTextureHost(uint64_t aID,
const ipc::Shmem& aShmem,
gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags)
: BufferTextureHost(aID, aFormat, aFlags)
, mShmem(new ipc::Shmem(aShmem))
, mDeallocator(aDeallocator)
{
MOZ_COUNT_CTOR(ShmemTextureHost);
}
ShmemTextureHost::~ShmemTextureHost()
{
DeallocateDeviceData();
delete mShmem;
MOZ_COUNT_DTOR(ShmemTextureHost);
}
void
ShmemTextureHost::DeallocateSharedData()
{
if (mShmem) {
MOZ_ASSERT(mDeallocator,
"Shared memory would leak without a ISurfaceAllocator");
mDeallocator->DeallocShmem(*mShmem);
}
}
uint8_t* ShmemTextureHost::GetBuffer()
{
return mShmem ? mShmem->get<uint8_t>() : nullptr;
}
MemoryTextureHost::MemoryTextureHost(uint64_t aID,
uint8_t* aBuffer,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
: BufferTextureHost(aID, aFormat, aFlags)
, mBuffer(aBuffer)
{
MOZ_COUNT_CTOR(MemoryTextureHost);
}
MemoryTextureHost::~MemoryTextureHost()
{
DeallocateDeviceData();
MOZ_COUNT_DTOR(ShmemTextureHost);
}
void
MemoryTextureHost::DeallocateSharedData()
{
delete[] mBuffer;
}
uint8_t* MemoryTextureHost::GetBuffer()
{
return mBuffer;
}
} // namespace
} // namespace

View File

@ -18,6 +18,12 @@
class gfxReusableSurfaceWrapper;
class gfxImageSurface;
namespace mozilla {
namespace gfx {
class DataSourceSurface;
}
}
namespace mozilla {
namespace layers {
@ -28,9 +34,10 @@ class TextureSourceOGL;
class TextureSourceD3D11;
class TextureSourceBasic;
class TextureParent;
class DataTextureSource;
/**
* A view on a DeprecatedTextureHost where the texture is internally represented as tiles
* A view on a TextureHost where the texture is internally represented as tiles
* (contrast with a tiled buffer, where each texture is a tile). For iteration by
* the texture's buffer host.
* This is only useful when the underlying surface is too big to fit in one
@ -69,31 +76,42 @@ public:
}
/**
* Returns the size of the texture in texels.
* If the underlying texture host is a tile iterator, GetSize must return the
* size of the current tile.
* Return the size of the texture in texels.
* If this is a tile iterator, GetSize must return the size of the current tile.
*/
virtual gfx::IntSize GetSize() const = 0;
/**
* Return the pixel format of this texture
*/
virtual gfx::SurfaceFormat GetFormat() const { return gfx::FORMAT_UNKNOWN; }
/**
* Cast to an TextureSource for the OpenGL backend.
* Cast to a TextureSource for the OpenGL backend.
*/
virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
/**
* Cast to an TextureSource for the D3D11 backend.
* Cast to a TextureSource for the D3D11 backend.
*/
virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
/**
* Cast to a TextureSource for the software backend.
*/
virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
/**
* Cast to a DataTextureSurce.
*/
virtual DataTextureSource* AsDataTextureSource() { return nullptr; }
/**
* In some rare cases we currently need to consider a group of textures as one
* TextureSource, that can be split in sub-TextureSources.
*/
virtual TextureSource* GetSubSource(int index) { return nullptr; }
/**
* Overload this if the TextureSource supports big textures that don't fit in
* one device texture and must be tiled internally.
@ -105,6 +123,394 @@ public:
#endif
};
/**
* XXX - merge this class with TextureSource when deprecated texture classes
* are completely removed.
*/
class NewTextureSource : public TextureSource
{
public:
NewTextureSource()
{
MOZ_COUNT_CTOR(NewTextureSource);
}
virtual ~NewTextureSource()
{
MOZ_COUNT_DTOR(NewTextureSource);
}
/**
* Should be overriden in order to deallocate the data that is associated
* with the rendering backend, such as GL textures.
*/
virtual void DeallocateDeviceData() = 0;
void SetNextSibling(NewTextureSource* aTexture)
{
mNextSibling = aTexture;
}
NewTextureSource* GetNextSibling() const
{
return mNextSibling;
}
// temporary adapter to use the same SubSource API as the old TextureSource
virtual TextureSource* GetSubSource(int index) MOZ_OVERRIDE
{
switch (index) {
case 0: return this;
case 1: return GetNextSibling();
case 2: return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
}
return nullptr;
}
protected:
RefPtr<NewTextureSource> mNextSibling;
};
/**
* Interface for TextureSources that can be updated from a DataSourceSurface.
*
* All backend should implement at least one DataTextureSource.
*/
class DataTextureSource : public NewTextureSource
{
public:
DataTextureSource()
: mUpdateSerial(0)
{}
virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; }
/**
* Upload a (portion of) surface to the TextureSource.
*
* The DataTextureSource doesn't own aSurface, although it owns and manage
* the device texture it uploads to internally.
*/
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) = 0;
/**
* A facility to avoid reuploading when it is not necessary.
* The caller of Update can use GetUpdateSerial to see if the number has changed
* since last update, and call SetUpdateSerial after each successful update.
* The caller is responsible for managing the update serial except when the
* texture data is deallocated in which case the TextureSource should always
* reset the update serial to zero.
*/
uint32_t GetUpdateSerial() const { return mUpdateSerial; }
void SetUpdateSerial(uint32_t aValue) { mUpdateSerial = aValue; }
// By default at least set the update serial to zero.
// overloaded versions should do that too.
virtual void DeallocateDeviceData() MOZ_OVERRIDE
{
SetUpdateSerial(0);
}
/**
* Provide read access to the data as a DataSourceSurface.
*
* This is expected to be very slow and should be used for mostly debugging.
* XXX - implement everywhere and make it pure virtual.
*/
virtual TemporaryRef<gfx::DataSourceSurface> ReadBack() { return nullptr; };
private:
uint32_t mUpdateSerial;
};
/**
* TextureHost is a thin abstraction over texture data that need to be shared
* between the content process and the compositor process. It is the
* compositor-side half of a TextureClient/TextureHost pair. A corresponding
* TextureClient lives on the content-side.
*
* TextureHost only knows how to deserialize or synchronize generic image data
* (SurfaceDescriptor) and provide access to one or more TextureSource objects
* (these provide the necessary APIs for compositor backends to composite the
* image).
*
* A TextureHost implementation corresponds to one SurfaceDescriptor type, as
* opposed to TextureSource that corresponds to device textures.
* This means that for YCbCr planes, even though they are represented as
* 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
* because the 3 planes are stored in the same buffer of shared memory, before
* they are uploaded separately.
*
* There is always one and only one TextureHost per TextureClient, and the
* TextureClient/Host pair only owns one buffer of image data through its
* lifetime. This means that the lifetime of the underlying shared data
* matches the lifetime of the TextureClient/Host pair. It also means
* TextureClient/Host do not implement double buffering, which is the
* reponsibility of the compositable (which would use two Texture pairs).
*
* The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
*
*/
class TextureHost : public RefCounted<TextureHost>
{
public:
TextureHost(uint64_t aID,
TextureFlags aFlags)
: mID(aID)
, mNextTexture(nullptr)
, mFlags(aFlags)
{}
virtual ~TextureHost() {}
/**
* Factory method.
*/
static TemporaryRef<TextureHost> Create(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
/**
* Lock the texture host for compositing.
*/
virtual bool Lock() { return true; }
/**
* Unlock the texture host after compositing.
*/
virtual void Unlock() {}
/**
* Note that the texture host format can be different from its corresponding
* texture source's. For example a ShmemTextureHost can have the ycbcr
* format and produce 3 "alpha" textures sources.
*/
virtual gfx::SurfaceFormat GetFormat() const = 0;
/**
* Return a list of TextureSources for use with a Compositor.
*
* This can trigger texture uploads, so do not call it inside transactions
* so as to not upload textures while the main thread is blocked.
* Must not be called while this TextureHost is not sucessfully Locked.
*/
virtual NewTextureSource* GetTextureSources() = 0;
/**
* Is called before compositing if the shared data has changed since last
* composition.
* This method should be overload in cases like when we need to do a texture
* upload for example.
*
* @param aRegion The region that has been changed, if nil, it means that the
* entire surface should be updated.
*/
virtual void Updated(const nsIntRegion* aRegion) {}
/**
* Sets this TextureHost's compositor.
* A TextureHost can change compositor on certain occasions, in particular if
* it belongs to an async Compositable.
* aCompositor can be null, in which case the TextureHost must cleanup all
* of it's device textures.
*/
virtual void SetCompositor(Compositor* aCompositor) {}
/**
* Should be overriden in order to deallocate the data that is associated
* with the rendering backend, such as GL textures.
*/
virtual void DeallocateDeviceData() {}
/**
* Should be overriden in order to deallocate the data that is shared with
* the content side, such as shared memory.
*/
virtual void DeallocateSharedData() {}
/**
* An ID to differentiate TextureHosts of a given CompositableHost.
*
* A TextureHost and its corresponding TextureClient always have the same ID.
* TextureHosts of a given CompositableHost always have different IDs.
* TextureHosts of different CompositableHosts, may have the same ID.
* Zero is always an invalid ID.
*/
uint64_t GetID() const { return mID; }
virtual gfx::IntSize GetSize() const = 0;
/**
* TextureHosts are kept as a linked list in their compositable
* XXX - This is just a poor man's PTexture. The purpose of this list is
* to keep TextureHost alive which should be independent from compositables.
* It will be removed when we add the PTetxure protocol (which will more
* gracefully handle the lifetime of textures). See bug 897452
*/
TextureHost* GetNextSibling() const { return mNextTexture; }
void SetNextSibling(TextureHost* aNext) { mNextTexture = aNext; }
/**
* Debug facility.
* XXX - cool kids use Moz2D
*/
virtual already_AddRefed<gfxImageSurface> GetAsSurface() = 0;
/**
* XXX - Flags should only be set at creation time, this will be removed.
*/
void SetFlags(TextureFlags aFlags) { mFlags = aFlags; }
/**
* XXX - Flags should only be set at creation time, this will be removed.
*/
void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
TextureFlags GetFlags() { return mFlags; }
/**
* Specific to B2G's Composer2D
* XXX - more doc here
*/
virtual LayerRenderState GetRenderState()
{
// By default we return an empty render state, this should be overriden
// by the TextureHost implementations that are used on B2G with Composer2D
return LayerRenderState();
}
#ifdef MOZ_LAYERS_HAVE_LOG
virtual void PrintInfo(nsACString& aTo, const char* aPrefix)
{
RefPtr<TextureSource> source = GetTextureSources();
if (source) {
source->PrintInfo(aTo, aPrefix);
}
}
#endif
protected:
uint64_t mID;
RefPtr<TextureHost> mNextTexture;
TextureFlags mFlags;
};
/**
* TextureHost that wraps a random access buffer such as a Shmem or some raw
* memory.
*
* This TextureHost is backend-independent and the backend-specific bits are
* in the TextureSource.
* This class must be inherited to implement GetBuffer and DeallocSharedData
* (see ShmemTextureHost and MemoryTextureHost)
*
* Uploads happen when Lock is called.
*
* BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
*/
class BufferTextureHost : public TextureHost
{
public:
BufferTextureHost(uint64_t aID,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags);
~BufferTextureHost();
virtual uint8_t* GetBuffer() = 0;
virtual void Updated(const nsIntRegion* aRegion) MOZ_OVERRIDE;
virtual bool Lock() MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE;
virtual void DeallocateDeviceData() MOZ_OVERRIDE;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
/**
* Return the format that is exposed to the compositor when calling
* GetTextureSources.
*
* If the shared format is YCbCr and the compositor does not support it,
* GetFormat will be RGB32 (even though mFormat is FORMAT_YUV).
*/
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
protected:
bool Upload(nsIntRegion *aRegion = nullptr);
Compositor* mCompositor;
RefPtr<DataTextureSource> mFirstSource;
nsIntRegion mMaybeUpdatedRegion;
gfx::IntSize mSize;
// format of the data that is shared with the content process.
gfx::SurfaceFormat mFormat;
uint32_t mUpdateSerial;
bool mLocked;
bool mPartialUpdate;
};
/**
* TextureHost that wraps shared memory.
* the corresponding texture on the client side is ShmemTextureClient.
* This TextureHost is backend-independent.
*/
class ShmemTextureHost : public BufferTextureHost
{
public:
ShmemTextureHost(uint64_t aID,
const ipc::Shmem& aShmem,
gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
~ShmemTextureHost();
virtual void DeallocateSharedData() MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
protected:
ipc::Shmem* mShmem;
ISurfaceAllocator* mDeallocator;
};
/**
* TextureHost that wraps raw memory.
* The corresponding texture on the client side is MemoryTextureClient.
* Can obviously not be used in a cross process setup.
* This TextureHost is backend-independent.
*/
class MemoryTextureHost : public BufferTextureHost
{
public:
MemoryTextureHost(uint64_t aID,
uint8_t* aBuffer,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags);
~MemoryTextureHost();
virtual void DeallocateSharedData() MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
protected:
uint8_t* mBuffer;
};
/**
* XXX - This class is deprectaed, will be removed soon.
*
@ -123,7 +529,7 @@ public:
* 3 textures internally, use 1 DeprecatedTextureHost and not 3, because the 3 planes
* arrive in the same IPC message.
*
* The Lock/Unlock mecanism here mirrors Lock/Unlock in DeprecatedTextureClient. These two
* The Lock/Unlock mechanism here mirrors Lock/Unlock in DeprecatedTextureClient. These two
* methods don't always have to use blocking locks, unless a resource is shared
* between the two sides (like shared texture handles). For instance, in some
* cases the data received in Update(...) is a copy in shared memory of the data
@ -347,9 +753,8 @@ protected:
// which can go away under our feet at any time. This is the cause
// of bug 862324 among others. Our current understanding is that
// this will be gone in Gecko 24. See bug 858914.
gfx::SurfaceFormat mFormat;
ISurfaceAllocator* mDeAllocator;
gfx::SurfaceFormat mFormat;
};
class AutoLockDeprecatedTextureHost
@ -392,6 +797,17 @@ public:
#endif
};
/**
* Creates a TextureHost that can be used with any of the existing backends
* Not all SurfaceDescriptor types are supported
*/
TemporaryRef<TextureHost>
CreateBackendIndependentTextureHost(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
}
}
#endif

View File

@ -8,6 +8,7 @@
#include "ContentHost.h"
#include "ClientTiledThebesLayer.h" // for BasicTiledLayerBuffer
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {

View File

@ -47,6 +47,9 @@ public:
virtual TextureFactoryIdentifier
GetTextureFactoryIdentifier() MOZ_OVERRIDE;
virtual TemporaryRef<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE { return nullptr; }
virtual bool CanUseCanvasLayerForSize(const gfxIntSize& aSize) MOZ_OVERRIDE;
virtual int32_t GetMaxTextureSize() const MOZ_FINAL;

View File

@ -8,6 +8,7 @@
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/TextureHost.h"
#include "gfxWindowsPlatform.h"
#include <d3d11.h>
#include <vector>

View File

@ -20,6 +20,7 @@ class TextureFactoryIdentifier;
class SurfaceDescriptor;
class ThebesBufferData;
class DeprecatedTextureClient;
class TextureClient;
class BasicTiledLayerBuffer;
/**
@ -141,6 +142,42 @@ public:
*/
virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) = 0;
/**
* Tell the compositor side to create a TextureHost that corresponds to
* aClient.
*/
virtual void AddTexture(CompositableClient* aCompositable,
TextureClient* aClient) = 0;
/**
* Tell the compositor side to delete the TextureHost corresponding to
* aTextureID.
* By default the shared Data is deallocated along with the TextureHost, but
* this behaviour can be overriden by the TextureFlags passed here.
* XXX - This is kind of bad, but for now we have to do this, because of some
* edge cases caused by the lifetime of the TextureHost being limited by the
* lifetime of the CompositableHost. We should be able to remove this flags
* parameter when we remove the lifetime constraint.
*/
virtual void RemoveTexture(CompositableClient* aCompositable,
uint64_t aTextureID,
TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) = 0;
/**
* Tell the CompositableHost on the compositor side what texture to use for
* the next composition.
*/
virtual void UseTexture(CompositableClient* aCompositable,
TextureClient* aClient) = 0;
/**
* Tell the compositor side that the shared data has been modified so that
* it can react accordingly (upload textures, etc.).
*/
virtual void UpdatedTexture(CompositableClient* aCompositable,
TextureClient* aTexture,
nsIntRegion* aRegion) = 0;
void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);
/**

View File

@ -15,11 +15,34 @@
#include "TiledLayerBuffer.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/ThebesLayerComposite.h"
#include "mozilla/layers/TextureHost.h"
#include "CompositorParent.h"
namespace mozilla {
namespace layers {
template<typename T>
CompositableHost* AsCompositable(const T& op)
{
return static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost();
}
template<typename T>
bool ScheduleComposition(const T& op)
{
CompositableParent* comp = static_cast<CompositableParent*>(op.compositableParent());
if (!comp || !comp->GetCompositorID()) {
return false;
}
CompositorParent* cp
= CompositorParent::GetCompositor(comp->GetCompositorID());
if (!cp) {
return false;
}
cp->ScheduleComposition();
return true;
}
bool
CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
EditReplyVector& replyv)
@ -101,12 +124,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
op.textureId(), newBack));
}
if (shouldRecomposite && compositableParent->GetCompositorID()) {
CompositorParent* cp
= CompositorParent::GetCompositor(compositableParent->GetCompositorID());
if (cp) {
cp->ScheduleComposition();
}
if (shouldRecomposite) {
ScheduleComposition(op);
}
}
@ -181,6 +200,91 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
tileComposer->PaintedTiledLayerBuffer(p);
break;
}
case CompositableOperation::TOpUseTexture: {
const OpUseTexture& op = aEdit.get_OpUseTexture();
if (op.textureID() == 0) {
NS_WARNING("Invalid texture ID");
break;
}
CompositableHost* compositable = AsCompositable(op);
RefPtr<TextureHost> tex = compositable->GetTextureHost(op.textureID());
MOZ_ASSERT(tex.get());
compositable->UseTextureHost(tex);
if (!ScheduleComposition(op)) {
NS_WARNING("could not find a compositor to schedule composition");
}
break;
}
case CompositableOperation::TOpAddTexture: {
const OpAddTexture& op = aEdit.get_OpAddTexture();
if (op.textureID() == 0) {
NS_WARNING("Invalid texture ID");
break;
}
CompositableHost* compositable = AsCompositable(op);
RefPtr<TextureHost> tex = TextureHost::Create(op.textureID(),
op.data(),
this,
op.textureFlags());
MOZ_ASSERT(tex.get());
tex->SetCompositor(compositable->GetCompositor());
compositable->AddTextureHost(tex);
MOZ_ASSERT(compositable->GetTextureHost(op.textureID()) == tex.get());
break;
}
case CompositableOperation::TOpRemoveTexture: {
const OpRemoveTexture& op = aEdit.get_OpRemoveTexture();
if (op.textureID() == 0) {
NS_WARNING("Invalid texture ID");
break;
}
CompositableHost* compositable = AsCompositable(op);
RefPtr<TextureHost> texture = compositable->GetTextureHost(op.textureID());
MOZ_ASSERT(texture);
TextureFlags flags = texture->GetFlags();
if (flags & TEXTURE_DEALLOCATE_HOST) {
texture->DeallocateSharedData();
}
compositable->RemoveTextureHost(op.textureID());
// if it is not the host that deallocates the shared data, then we need
// to notfy the client side to tell when it is safe to deallocate or
// reuse it.
if (!(flags & TEXTURE_DEALLOCATE_HOST)) {
replyv.push_back(ReplyTextureRemoved(op.compositableParent(), nullptr,
op.textureID()));
}
break;
}
case CompositableOperation::TOpUpdateTexture: {
const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
if (op.textureID() == 0) {
NS_WARNING("Invalid texture ID");
break;
}
CompositableHost* compositable = AsCompositable(op);
MOZ_ASSERT(compositable);
RefPtr<TextureHost> texture = compositable->GetTextureHost(op.textureID());
MOZ_ASSERT(texture);
if (op.region().type() == MaybeRegion::TnsIntRegion) {
nsIntRegion region = op.region().get_nsIntRegion();
texture->Updated(&region);
} else {
// no region means invalidate the entire surface
texture->Updated(nullptr);
}
compositable->UseTextureHost(texture);
break;
}
default: {
MOZ_ASSERT(false, "bad type");
}

View File

@ -19,8 +19,6 @@ typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
// through this interface.
class CompositableParentManager : public ISurfaceAllocator
{
public:
protected:
/**
* Handle the IPDL messages that affect PCompositable actors.

View File

@ -164,6 +164,12 @@ CompositorParent::CompositorThreadID()
return sCompositorThread ? sCompositorThread->thread_id() : sCompositorThreadID;
}
bool
CompositorParent::IsInCompositorThread()
{
return CompositorThreadID() == PlatformThread::CurrentId();
}
CompositorParent::~CompositorParent()
{
MOZ_COUNT_DTOR(CompositorParent);

View File

@ -175,6 +175,10 @@ public:
*/
static void SetTimeAndSampleAnimations(TimeStamp aTime, bool aIsTesting);
/**
* Returns true if the calling thrad is the compositor thread.
*/
static bool IsInCompositorThread();
protected:
virtual PLayerTransactionParent*
AllocPLayerTransactionParent(const LayersBackend& aBackendHint,
@ -193,7 +197,7 @@ private:
void ResumeCompositionAndResize(int width, int height);
void ForceComposition();
inline PlatformThreadId CompositorThreadID();
inline static PlatformThreadId CompositorThreadID();
/**
* Creates a global map referencing each compositor by ID.

View File

@ -120,10 +120,6 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
if (!aSurface) {
return;
}
if (!IsOnCompositorSide() && ReleaseOwnedSurfaceDescriptor(*aSurface)) {
*aSurface = SurfaceDescriptor();
return;
}
if (PlatformDestroySharedSurface(aSurface)) {
return;
}
@ -151,38 +147,6 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
*aSurface = SurfaceDescriptor();
}
bool IsSurfaceDescriptorOwned(const SurfaceDescriptor& aDescriptor)
{
switch (aDescriptor.type()) {
case SurfaceDescriptor::TYCbCrImage: {
const YCbCrImage& ycbcr = aDescriptor.get_YCbCrImage();
return ycbcr.owner() != 0;
}
case SurfaceDescriptor::TRGBImage: {
const RGBImage& rgb = aDescriptor.get_RGBImage();
return rgb.owner() != 0;
}
default:
return false;
}
return false;
}
bool ReleaseOwnedSurfaceDescriptor(const SurfaceDescriptor& aDescriptor)
{
DeprecatedSharedPlanarYCbCrImage* sharedYCbCr =
DeprecatedSharedPlanarYCbCrImage::FromSurfaceDescriptor(aDescriptor);
if (sharedYCbCr) {
sharedYCbCr->Release();
return true;
}
DeprecatedSharedRGBImage* sharedRGB = DeprecatedSharedRGBImage::FromSurfaceDescriptor(aDescriptor);
if (sharedRGB) {
sharedRGB->Release();
return true;
}
return false;
}
#if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfxIntSize&,

View File

@ -78,6 +78,51 @@ struct AutoEndTransaction {
CompositableTransaction* mTxn;
};
void
ImageBridgeChild::AddTexture(CompositableClient* aCompositable,
TextureClient* aTexture)
{
SurfaceDescriptor descriptor;
if (!aTexture->ToSurfaceDescriptor(descriptor)) {
NS_WARNING("ImageBridge: Failed to serialize a TextureClient");
return;
}
mTxn->AddEdit(OpAddTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID(),
descriptor,
aTexture->GetFlags()));
}
void
ImageBridgeChild::RemoveTexture(CompositableClient* aCompositable,
uint64_t aTexture,
TextureFlags aFlags)
{
mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture,
aFlags));
}
void
ImageBridgeChild::UseTexture(CompositableClient* aCompositable,
TextureClient* aTexture)
{
mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID()));
}
void
ImageBridgeChild::UpdatedTexture(CompositableClient* aCompositable,
TextureClient* aTexture,
nsIntRegion* aRegion)
{
MaybeRegion region = aRegion ? MaybeRegion(*aRegion)
: MaybeRegion(null_t());
mTxn->AddNoSwapEdit(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID(),
region));
}
void
ImageBridgeChild::UpdateTexture(CompositableClient* aCompositable,
TextureIdentifier aTextureId,
@ -304,6 +349,7 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine
MOZ_ASSERT(aContainer);
sImageBridgeChildSingleton->BeginTransaction();
aClient->UpdateImage(aContainer, Layer::CONTENT_OPAQUE);
aClient->OnTransaction();
sImageBridgeChildSingleton->EndTransaction();
}
@ -337,10 +383,6 @@ ImageBridgeChild::EndTransaction()
AutoEndTransaction _(mTxn);
if (mTxn->IsEmpty()) {
return;
}
AutoInfallibleTArray<CompositableOperation, 10> cset;
cset.SetCapacity(mTxn->mOperations.size());
if (!mTxn->mOperations.empty()) {

View File

@ -28,7 +28,7 @@ class CompositableClient;
class CompositableTransaction;
class ShadowableLayer;
class Image;
class TextureClient;
/**
* Returns true if the current thread is the ImageBrdigeChild's thread.
@ -232,6 +232,32 @@ public:
virtual void Connect(CompositableClient* aCompositable) MOZ_OVERRIDE;
/**
* See CompositableForwarder::AddTexture
*/
virtual void AddTexture(CompositableClient* aCompositable,
TextureClient* aClient) MOZ_OVERRIDE;
/**
* See CompositableForwarder::RemoveTexture
*/
virtual void RemoveTexture(CompositableClient* aCompositable,
uint64_t aTextureID,
TextureFlags aFlags) MOZ_OVERRIDE;
/**
* See CompositableForwarder::UpdatedTexture
*/
virtual void UpdatedTexture(CompositableClient* aCompositable,
TextureClient* aTexture,
nsIntRegion* aRegion) MOZ_OVERRIDE;
/**
* See CompositableForwarder::UseTexture
*/
virtual void UseTexture(CompositableClient* aCompositable,
TextureClient* aClient) MOZ_OVERRIDE;
virtual void PaintedTiledLayerBuffer(CompositableClient* aCompositable,
BasicTiledLayerBuffer* aTiledLayerBuffer) MOZ_OVERRIDE
{

View File

@ -290,6 +290,47 @@ struct OpUpdatePictureRect {
nsIntRect picture;
};
/**
* Provides the compositor side with enough information to create a
* TextureHost.
*/
struct OpAddTexture {
PCompositable compositable;
uint64_t textureID;
SurfaceDescriptor data;
uint32_t textureFlags;
};
/**
* Tells the compositor-side to remove the corresponding TextureHost and
* deallocate its data.
*/
struct OpRemoveTexture {
PCompositable compositable;
uint64_t textureID;
uint32_t flags;
};
/**
* Tells the compositor-side which texture to use (for example, as front buffer
* if there is several textures for double buffering)
*/
struct OpUseTexture {
PCompositable compositable;
uint64_t textureID;
};
union MaybeRegion {
nsIntRegion;
null_t;
};
struct OpUpdateTexture {
PCompositable compositable;
uint64_t textureID;
MaybeRegion region;
};
union CompositableOperation {
OpUpdatePictureRect;
@ -302,6 +343,11 @@ union CompositableOperation {
OpPaintTextureIncremental;
OpPaintTiledLayerBuffer;
OpAddTexture;
OpRemoveTexture;
OpUpdateTexture;
OpUseTexture;
};
// A unit of a changeset; a set of these comprise a changeset
@ -343,11 +389,19 @@ struct OpTextureSwap {
SurfaceDescriptor image;
};
struct ReplyTextureRemoved {
PCompositable compositable;
uint32_t textureId;
};
// Unit of a "changeset reply". This is a weird abstraction, probably
// only to be used for buffer swapping.
union EditReply {
OpContentBufferSwap;
OpTextureSwap;
// new stuff
ReplyTextureRemoved;
};
} // namespace

View File

@ -396,6 +396,8 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
case Edit::TOpAttachCompositable: {
const OpAttachCompositable& op = edit.get_OpAttachCompositable();
Attach(cast(op.layerParent()), cast(op.compositableParent()));
cast(op.compositableParent())->SetCompositorID(
mLayerManager->GetCompositor()->GetCompositorID());
break;
}
case Edit::TOpAttachAsyncCompositable: {

View File

@ -5,6 +5,7 @@
include protocol PGrallocBuffer;
include "gfxipc/ShadowLayerUtils.h";
include "mozilla/gfx/Types.h";
using gfx3DMatrix;
using gfxIntSize;
@ -24,6 +25,8 @@ using mozilla::WindowsHandle;
using mozilla::gl::SharedTextureHandle;
using mozilla::gl::GLContext::SharedTextureShareType;
using mozilla::gfx::SurfaceStreamHandle;
using mozilla::gfx::SurfaceFormat;
using mozilla::gfx::IntSize;
namespace mozilla {
namespace layers {
@ -45,6 +48,7 @@ struct SharedTextureDescriptor {
bool inverted;
};
// XXX - soon to be removed
struct SurfaceDescriptorGralloc {
PGrallocBuffer buffer;
/**
@ -80,6 +84,7 @@ struct SurfaceStreamDescriptor {
bool yflip;
};
// XXX - can be removed as soon as DeprecatedImageClientSingle is removed
struct YCbCrImage {
Shmem data;
uint64_t owner;
@ -100,16 +105,34 @@ struct MemoryImage {
uint32_t format;
};
/**
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
*/
struct SurfaceDescriptorShmem {
Shmem data;
SurfaceFormat format;
};
/**
* Used for "raw memory"-backed YCbCr and (flavors of) RGBA textures
*/
struct SurfaceDescriptorMemory {
uintptr_t data;
SurfaceFormat format;
};
union SurfaceDescriptor {
Shmem;
SurfaceDescriptorShmem;
SurfaceDescriptorMemory;
SurfaceDescriptorD3D10;
SurfaceDescriptorGralloc;
SurfaceDescriptorX11;
YCbCrImage;
RGBImage;
SharedTextureDescriptor;
SurfaceStreamDescriptor;
MemoryImage;
YCbCrImage; // XXX - deprecated
SurfaceDescriptorGralloc; // XXX - deprecated
Shmem; // XXX - deprecated
RGBImage; // XXX - deprecated
MemoryImage; // XXX - deprecated
null_t;
};

View File

@ -374,6 +374,53 @@ ShadowLayerForwarder::UpdatePictureRect(CompositableClient* aCompositable,
mTxn->AddNoSwapPaint(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect));
}
void
ShadowLayerForwarder::AddTexture(CompositableClient* aCompositable,
TextureClient* aTexture)
{
SurfaceDescriptor descriptor;
if (!aTexture->ToSurfaceDescriptor(descriptor)) {
NS_WARNING("Failed to serialize a TextureClient");
return;
}
mTxn->AddEdit(OpAddTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID(),
descriptor,
aTexture->GetFlags()));
}
void
ShadowLayerForwarder::RemoveTexture(CompositableClient* aCompositable,
uint64_t aTexture,
TextureFlags aFlags)
{
mTxn->AddEdit(OpRemoveTexture(nullptr,
aCompositable->GetIPDLActor(),
aTexture,
aFlags));
}
void
ShadowLayerForwarder::UpdatedTexture(CompositableClient* aCompositable,
TextureClient* aTexture,
nsIntRegion* aRegion)
{
printf("ShadowLayerForwarder::UpdatedTexture %i\n", (int)aTexture->GetID());
MaybeRegion region = aRegion ? MaybeRegion(*aRegion)
: MaybeRegion(null_t());
mTxn->AddEdit(OpUpdateTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID(),
region));
}
void
ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable,
TextureClient* aTexture)
{
mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
aTexture->GetID()));
}
bool
ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
{

View File

@ -52,11 +52,13 @@ class Transaction;
class SurfaceDescriptor;
class CanvasSurface;
class DeprecatedTextureClientShmem;
class ShmemTextureClient;
class ContentClientRemote;
class CompositableChild;
class ImageClient;
class CanvasClient;
class ContentClient;
class TextureClient;
/**
@ -303,6 +305,32 @@ public:
void UpdatePictureRect(CompositableClient* aCompositable,
const nsIntRect& aRect);
/**
* See CompositableForwarder::AddTexture
*/
virtual void AddTexture(CompositableClient* aCompositable,
TextureClient* aClient) MOZ_OVERRIDE;
/**
* See CompositableForwarder::RemoveTexture
*/
virtual void RemoveTexture(CompositableClient* aCompositable,
uint64_t aTextureID,
TextureFlags aFlags) MOZ_OVERRIDE;
/**
* See CompositableForwarder::UpdatedTexture
*/
virtual void UpdatedTexture(CompositableClient* aCompositable,
TextureClient* aTexture,
nsIntRegion* aRegion) MOZ_OVERRIDE;
/**
* See CompositableForwarder::UseTexture
*/
virtual void UseTexture(CompositableClient* aCompositable,
TextureClient* aClient) MOZ_OVERRIDE;
/**
* End the current transaction and forward it to LayerManagerComposite.
* |aReplies| are directions from the LayerManagerComposite to the

View File

@ -7,12 +7,26 @@
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "ISurfaceAllocator.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/ImageClient.h"
namespace mozilla {
namespace layers {
using namespace mozilla::ipc;
SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
: PlanarYCbCrImage(nullptr)
{
mTextureClient = aCompositable->CreateBufferTextureClient(gfx::FORMAT_YUV);
MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
}
SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
}
DeprecatedSharedPlanarYCbCrImage::~DeprecatedSharedPlanarYCbCrImage() {
MOZ_COUNT_DTOR(DeprecatedSharedPlanarYCbCrImage);
@ -23,6 +37,149 @@ DeprecatedSharedPlanarYCbCrImage::~DeprecatedSharedPlanarYCbCrImage() {
}
}
TextureClient*
SharedPlanarYCbCrImage::GetTextureClient()
{
return mTextureClient.get();
}
uint8_t*
SharedPlanarYCbCrImage::GetBuffer()
{
return mTextureClient->GetBuffer();
}
already_AddRefed<gfxASurface>
SharedPlanarYCbCrImage::GetAsSurface()
{
if (!mTextureClient->IsAllocated()) {
NS_WARNING("Can't get as surface");
return nullptr;
}
return PlanarYCbCrImage::GetAsSurface();
}
void
SharedPlanarYCbCrImage::SetData(const PlanarYCbCrImage::Data& aData)
{
// If mShmem has not been allocated (through Allocate(aData)), allocate it.
// This code path is slower than the one used when Allocate has been called
// since it will trigger a full copy.
if (!mTextureClient->IsAllocated()) {
Data data = aData;
if (!Allocate(data)) {
printf("SharedPlanarYCbCrImage::SetData failed to allocate :(\n");
return;
}
}
MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
return;
}
// do not set mBuffer like in PlanarYCbCrImage because the later
// will try to manage this memory without knowing it belongs to a
// shmem.
mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
mData.mCbCrSize);
mSize = mData.mPicSize;
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
mData.mYChannel = serializer.GetYData();
mData.mCbChannel = serializer.GetCbData();
mData.mCrChannel = serializer.GetCrData();
mTextureClient->MarkImmutable();
}
// needs to be overriden because the parent class sets mBuffer which we
// do not want to happen.
uint8_t*
SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
{
NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), "This image already has allocated data");
size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize);
// update buffer size
mBufferSize = size;
// get new buffer _without_ setting mBuffer.
bool status = mTextureClient->Allocate(mBufferSize);
MOZ_ASSERT(status);
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
return serializer.GetData();
}
void
SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
{
mData = aData;
mSize = aData.mPicSize;
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
serializer.InitializeBufferInfo(aData.mYSize,
aData.mCbCrSize);
}
uint8_t*
SharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
{
NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
"This image already has allocated data");
if (!mTextureClient->Allocate(aSize)) {
return nullptr;
}
return mTextureClient->GetBuffer();
}
bool
SharedPlanarYCbCrImage::IsValid() {
return mTextureClient->IsAllocated();
}
bool
SharedPlanarYCbCrImage::Allocate(PlanarYCbCrImage::Data& aData)
{
NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
"This image already has allocated data");
size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
aData.mCbCrSize);
if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
return false;
}
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
serializer.InitializeBufferInfo(aData.mYSize,
aData.mCbCrSize);
MOZ_ASSERT(serializer.IsValid());
aData.mYChannel = serializer.GetYData();
aData.mCbChannel = serializer.GetCbData();
aData.mCrChannel = serializer.GetCrData();
// copy some of aData's values in mData (most of them)
mData.mYChannel = aData.mYChannel;
mData.mCbChannel = aData.mCbChannel;
mData.mCrChannel = aData.mCrChannel;
mData.mYSize = aData.mYSize;
mData.mCbCrSize = aData.mCbCrSize;
mData.mPicX = aData.mPicX;
mData.mPicY = aData.mPicY;
mData.mPicSize = aData.mPicSize;
mData.mStereoMode = aData.mStereoMode;
// those members are not always equal to aData's, due to potentially different
// packing.
mData.mYSkip = 0;
mData.mCbSkip = 0;
mData.mCrSkip = 0;
mData.mYStride = mData.mYSize.width;
mData.mCbCrStride = mData.mCbCrSize.width;
return true;
}
void
DeprecatedSharedPlanarYCbCrImage::SetData(const PlanarYCbCrImage::Data& aData)

View File

@ -15,7 +15,10 @@ namespace mozilla {
namespace layers {
class ImageClient;
class TextureClient;
class BufferTextureClient;
// XXX - This class will be removed along with DeprecatedImageClient
class DeprecatedSharedPlanarYCbCrImage : public PlanarYCbCrImage
{
public:
@ -82,6 +85,34 @@ private:
bool mAllocated;
};
class SharedPlanarYCbCrImage : public PlanarYCbCrImage
, public ISharedImage
{
public:
SharedPlanarYCbCrImage(ImageClient* aCompositable);
~SharedPlanarYCbCrImage();
virtual ISharedImage* AsSharedImage() MOZ_OVERRIDE { return this; }
virtual TextureClient* GetTextureClient() MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
virtual already_AddRefed<gfxASurface> GetAsSurface() MOZ_OVERRIDE;
virtual void SetData(const PlanarYCbCrImage::Data& aData) MOZ_OVERRIDE;
virtual void SetDataNoCopy(const Data &aData) MOZ_OVERRIDE;
virtual bool Allocate(PlanarYCbCrImage::Data& aData);
virtual uint8_t* AllocateBuffer(uint32_t aSize) MOZ_OVERRIDE;
// needs to be overriden because the parent class sets mBuffer which we
// do not want to happen.
virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) MOZ_OVERRIDE;
virtual bool IsValid() MOZ_OVERRIDE;
private:
RefPtr<BufferTextureClient> mTextureClient;
};
} // namespace
} // namespace

View File

@ -7,6 +7,9 @@
#include "mozilla/layers/LayersSurfaces.h"
#include "Shmem.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/ImageClient.h"
#include "gfx2DGlue.h"
// Just big enough for a 1080p RGBA32 frame
#define MAX_FRAME_SIZE (16 * 1024 * 1024)
@ -36,10 +39,10 @@ DeprecatedSharedRGBImage::~DeprecatedSharedRGBImage()
delete mShmem;
}
already_AddRefed<DeprecatedSharedRGBImage>
DeprecatedSharedRGBImage::Create(ImageContainer *aImageContainer,
nsIntSize aSize,
gfxImageFormat aImageFormat)
already_AddRefed<Image>
CreateSharedRGBImage(ImageContainer *aImageContainer,
nsIntSize aSize,
gfxImageFormat aImageFormat)
{
NS_ASSERTION(aImageFormat == gfxASurface::ImageFormatARGB32 ||
aImageFormat == gfxASurface::ImageFormatRGB24 ||
@ -59,16 +62,21 @@ DeprecatedSharedRGBImage::Create(ImageContainer *aImageContainer,
return nullptr;
}
nsRefPtr<DeprecatedSharedRGBImage> rgbImage = static_cast<DeprecatedSharedRGBImage*>(image.get());
rgbImage->mSize = gfxIntSize(aSize.width, aSize.height);
rgbImage->mImageFormat = aImageFormat;
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
nsRefPtr<DeprecatedSharedRGBImage> rgbImageDep = static_cast<DeprecatedSharedRGBImage*>(image.get());
rgbImageDep->mSize = gfxIntSize(aSize.width, aSize.height);
rgbImageDep->mImageFormat = aImageFormat;
if (!rgbImage->AllocateBuffer(aSize, aImageFormat)) {
NS_WARNING("Failed to allocate shared memory for DeprecatedSharedRGBImage");
return nullptr;
if (!rgbImageDep->AllocateBuffer(aSize, aImageFormat)) {
NS_WARNING("Failed to allocate shared memory for DeprecatedSharedRGBImage");
return nullptr;
}
return rgbImageDep.forget();
}
return rgbImage.forget();
nsRefPtr<SharedRGBImage> rgbImage = static_cast<SharedRGBImage*>(image.get());
rgbImage->Allocate(gfx::ToIntSize(aSize),
gfx::ImageFormatToSurfaceFormat(aImageFormat));
return image.forget();
}
uint8_t *
@ -157,6 +165,58 @@ DeprecatedSharedRGBImage::FromSurfaceDescriptor(const SurfaceDescriptor& aDescri
return reinterpret_cast<DeprecatedSharedRGBImage*>(rgb.owner());
}
SharedRGBImage::SharedRGBImage(ImageClient* aCompositable)
: Image(nullptr, SHARED_RGB)
, mCompositable(aCompositable)
{
MOZ_COUNT_CTOR(SharedRGBImage);
}
SharedRGBImage::~SharedRGBImage()
{
MOZ_COUNT_DTOR(SharedRGBImage);
}
bool
SharedRGBImage::Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
{
mSize = aSize;
mTextureClient = mCompositable->CreateBufferTextureClient(aFormat);
return mTextureClient->AllocateForSurface(aSize);
}
uint8_t*
SharedRGBImage::GetBuffer()
{
return mTextureClient ? mTextureClient->GetBuffer()
: nullptr;
}
gfxIntSize
SharedRGBImage::GetSize()
{
return ThebesIntSize(mSize);
}
size_t
SharedRGBImage::GetBufferSize()
{
return mTextureClient ? mTextureClient->GetBufferSize()
: 0;
}
TextureClient*
SharedRGBImage::GetTextureClient()
{
return mTextureClient.get();
}
already_AddRefed<gfxASurface>
SharedRGBImage::GetAsSurface()
{
return nullptr;
}
} // namespace layers
} // namespace mozilla

View File

@ -13,15 +13,26 @@ namespace ipc {
class Shmem;
}
namespace layers {
class BufferTextureClient;
class TextureClient;
class ImageClient;
already_AddRefed<Image> CreateSharedRGBImage(ImageContainer* aImageContainer,
nsIntSize aSize,
gfxASurface::gfxImageFormat aImageFormat);
/**
* Stores RGB data in shared memory
* It is assumed that the image width and stride are equal
*/
class DeprecatedSharedRGBImage : public Image
class DeprecatedSharedRGBImage : public Image,
public ISharedImage
{
typedef gfxASurface::gfxImageFormat gfxImageFormat;
friend already_AddRefed<Image> CreateSharedRGBImage(ImageContainer* aImageContainer,
nsIntSize aSize,
gfxASurface::gfxImageFormat aImageFormat);
public:
typedef gfxASurface::gfxImageFormat gfxImageFormat;
struct Header {
gfxImageFormat mImageFormat;
};
@ -29,9 +40,6 @@ public:
DeprecatedSharedRGBImage(ISurfaceAllocator *aAllocator);
~DeprecatedSharedRGBImage();
static already_AddRefed<DeprecatedSharedRGBImage> Create(ImageContainer* aImageContainer,
nsIntSize aSize,
gfxImageFormat aImageFormat);
uint8_t *GetBuffer();
gfxIntSize GetSize();
@ -61,9 +69,11 @@ public:
*/
static DeprecatedSharedRGBImage* FromSurfaceDescriptor(const SurfaceDescriptor& aDescriptor);
private:
bool AllocateBuffer(nsIntSize aSize, gfxImageFormat aImageFormat);
TextureClient* GetTextureClient() MOZ_OVERRIDE { return nullptr; }
protected:
gfxIntSize mSize;
gfxImageFormat mImageFormat;
ISurfaceAllocator* mSurfaceAllocator;
@ -72,6 +82,35 @@ private:
ipc::Shmem *mShmem;
};
/**
* Stores RGB data in shared memory
* It is assumed that the image width and stride are equal
*/
class SharedRGBImage : public Image
, public ISharedImage
{
typedef gfxASurface::gfxImageFormat gfxImageFormat;
public:
SharedRGBImage(ImageClient* aCompositable);
~SharedRGBImage();
virtual TextureClient* GetTextureClient() MOZ_OVERRIDE;
virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
gfxIntSize GetSize();
size_t GetBufferSize();
already_AddRefed<gfxASurface> GetAsSurface();
bool Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
private:
gfx::IntSize mSize;
RefPtr<ImageClient> mCompositable;
RefPtr<BufferTextureClient> mTextureClient;
};
} // namespace layers
} // namespace mozilla

View File

@ -94,6 +94,7 @@ EXPORTS.mozilla.layers += [
'CompositorTypes.h',
'D3D9SurfaceImage.h',
'Effects.h',
'ImageDataSerializer.h',
'LayersTypes.h',
'RenderTrace.h',
'YCbCrImageDataSerializer.h',
@ -213,6 +214,7 @@ CPP_SOURCES += [
'ImageBridgeParent.cpp',
'ImageClient.cpp',
'ImageContainer.cpp',
'ImageDataSerializer.cpp',
'ImageHost.cpp',
'ImageLayerComposite.cpp',
'ImageLayerOGL.cpp',

View File

@ -23,7 +23,6 @@ namespace layers {
class CompositingRenderTargetOGL : public CompositingRenderTarget
{
typedef gfxASurface::gfxContentType ContentType;
typedef mozilla::gl::GLContext GLContext;
// For lazy initialisation of the GL stuff
@ -151,6 +150,13 @@ public:
return gfx::IntSize(0, 0);
}
gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
// XXX - Should it be implemented ? is the above assert true ?
MOZ_ASSERT(false, "Not implemented");
return gfx::FORMAT_UNKNOWN;
}
const gfxMatrix& GetTransform() {
return mTransform;
}

View File

@ -945,7 +945,7 @@ CompositorOGL::GetProgramTypeForEffect(Effect *aEffect) const
TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
return ShaderProgramFromTargetAndFormat(source->GetTextureTarget(),
source->GetTextureFormat());
source->GetFormat());
}
case EFFECT_YCBCR:
return YCbCrLayerProgramType;
@ -1411,6 +1411,13 @@ CompositorOGL::Resume()
return true;
}
TemporaryRef<DataTextureSource>
CompositorOGL::CreateDataTextureSource(TextureFlags aFlags)
{
RefPtr<DataTextureSource> result =
new TextureImageTextureSourceOGL(mGLContext, !(aFlags & ForceSingleTile));
return result;
}
} /* layers */
} /* mozilla */

View File

@ -34,6 +34,9 @@ public:
virtual ~CompositorOGL();
virtual TemporaryRef<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
virtual bool Initialize() MOZ_OVERRIDE;
virtual void Destroy() MOZ_OVERRIDE;

View File

@ -4,13 +4,61 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/layers/CompositableClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "GLContext.h"
#include "gfxipc/ShadowLayerUtils.h"
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
SharedTextureClientOGL::SharedTextureClientOGL()
: mHandle(0), mIsCrossProcess(false), mInverted(false)
{
}
SharedTextureClientOGL::~SharedTextureClientOGL()
{
// the data is released by the host
}
bool
SharedTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
if (!IsAllocated()) {
return false;
}
nsIntSize nsSize(mSize.width, mSize.height);
aOutDescriptor = SharedTextureDescriptor(mIsCrossProcess ? gl::GLContext::CrossProcess
: gl::GLContext::SameProcess,
mHandle, nsSize, mInverted);
return true;
}
void
SharedTextureClientOGL::InitWith(gl::SharedTextureHandle aHandle,
gfx::IntSize aSize,
bool aIsCrossProcess,
bool aInverted)
{
MOZ_ASSERT(!IsAllocated());
mHandle = aHandle;
mSize = aSize;
mIsCrossProcess = aIsCrossProcess;
mInverted = aInverted;
}
bool
SharedTextureClientOGL::IsAllocated() const
{
return mHandle != 0;
}
DeprecatedTextureClientSharedOGL::DeprecatedTextureClientSharedOGL(CompositableForwarder* aForwarder,
const TextureInfo& aTextureInfo)
: DeprecatedTextureClient(aForwarder, aTextureInfo)

View File

@ -8,10 +8,47 @@
#include "mozilla/layers/TextureClient.h"
#include "ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
#include "GLContext.h" // For SharedTextureHandle
#ifdef MOZ_WIDGET_GONK
#include <ui/GraphicBuffer.h>
#endif
namespace mozilla {
namespace layers {
/**
* A TextureClient implementation to share TextureMemory that is already
* on the GPU, for the OpenGL backend.
*/
class SharedTextureClientOGL : public TextureClient
{
public:
SharedTextureClientOGL();
~SharedTextureClientOGL();
virtual bool IsAllocated() const MOZ_OVERRIDE;
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
void InitWith(gl::SharedTextureHandle aHandle,
gfx::IntSize aSize,
bool aIsCrossProcess = false,
bool aInverted = false);
gfx::IntSize GetSize() const { return mSize; }
protected:
gfx::IntSize mSize;
gl::SharedTextureHandle mHandle;
bool mIsCrossProcess;
bool mInverted;
};
class DeprecatedTextureClientSharedOGL : public DeprecatedTextureClient
{
public:

View File

@ -53,6 +53,35 @@ CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
return result.forget();
}
TemporaryRef<TextureHost>
CreateTextureHostOGL(uint64_t aID,
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorShmem:
case SurfaceDescriptor::TSurfaceDescriptorMemory: {
result = CreateBackendIndependentTextureHost(aID, aDesc,
aDeallocator, aFlags);
break;
}
case SurfaceDescriptor::TSharedTextureDescriptor: {
const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor();
result = new SharedTextureHostOGL(aID, aFlags,
desc.shareType(),
desc.handle(),
gfx::ToIntSize(desc.size()),
desc.inverted());
break;
}
default: return nullptr;
}
return result.forget();
}
static void
MakeTextureIfNeeded(gl::GLContext* gl, GLenum aTarget, GLuint& aTexture)
{
@ -102,6 +131,220 @@ WrapMode(gl::GLContext *aGl, bool aAllowRepeat)
return LOCAL_GL_CLAMP_TO_EDGE;
}
bool
TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion,
gfx::IntPoint* aSrcOffset)
{
MOZ_ASSERT(mGL);
if (!mGL) {
NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext");
return false;
}
MOZ_ASSERT(aSurface);
nsIntSize size = ThebesIntSize(aSurface->GetSize());
if (!mTexImage ||
mTexImage->GetSize() != size ||
mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) {
if (mAllowTiling) {
// XXX - clarify the which size we want to use. Some use cases may
// require the size of the destnation surface to be different from
// the size of aSurface.
mTexImage = mGL->CreateTextureImage(size,
gfx::ContentForFormat(aSurface->GetFormat()),
WrapMode(mGL, aFlags & AllowRepeat),
FlagsToGLFlags(aFlags));
} else {
mTexImage = CreateBasicTextureImage(mGL,
size,
gfx::ContentForFormat(aSurface->GetFormat()),
WrapMode(mGL, aFlags & AllowRepeat),
FlagsToGLFlags(aFlags));
}
}
mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
if (mTexImage->InUpdate()) {
mTexImage->EndUpdate();
}
return true;
}
gfx::IntSize
TextureImageTextureSourceOGL::GetSize() const
{
if (mTexImage) {
if (mIterating) {
nsIntRect rect = mTexImage->GetTileRect();
return gfx::IntSize(rect.width, rect.height);
}
return gfx::IntSize(mTexImage->GetSize().width, mTexImage->GetSize().height);
}
NS_WARNING("Trying to query the size of an empty TextureSource.");
return gfx::IntSize(0, 0);
}
gfx::SurfaceFormat
TextureImageTextureSourceOGL::GetFormat() const
{
MOZ_ASSERT(mTexImage);
return mTexImage->GetTextureFormat();
}
void
TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit)
{
MOZ_ASSERT(mTexImage,
"Trying to bind a TextureSource that does not have an underlying GL texture.");
mTexImage->BindTexture(aTextureUnit);
}
SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor,
gl::SharedTextureHandle aHandle,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
GLenum aWrapMode,
SharedTextureShareType aShareType,
gfx::IntSize aSize,
const gfx3DMatrix& aTexTransform)
: mTextureTransform(aTexTransform)
, mSize(aSize)
, mCompositor(aCompositor)
, mSharedHandle(aHandle)
, mFormat(aFormat)
, mShareType(aShareType)
, mTextureTarget(aTarget)
, mWrapMode(aWrapMode)
{}
void
SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit)
{
if (!gl()) {
NS_WARNING("Trying to bind a texture without a GLContext");
return;
}
GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, tex);
if (!gl()->AttachSharedHandle(mShareType, mSharedHandle)) {
NS_ERROR("Failed to bind shared texture handle");
return;
}
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
}
void
SharedTextureSourceOGL::DetachSharedHandle()
{
if (!gl()) {
return;
}
gl()->DetachSharedHandle(mShareType, mSharedHandle);
}
void
SharedTextureSourceOGL::SetCompositor(CompositorOGL* aCompositor)
{
mCompositor = aCompositor;
}
bool
SharedTextureSourceOGL::IsValid() const
{
return gl() != nullptr;
}
gl::GLContext*
SharedTextureSourceOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
SharedTextureHostOGL::SharedTextureHostOGL(uint64_t aID,
TextureFlags aFlags,
gl::GLContext::SharedTextureShareType aShareType,
gl::SharedTextureHandle aSharedHandle,
gfx::IntSize aSize,
bool inverted)
: TextureHost(aID, aFlags)
, mSize(aSize)
, mCompositor(nullptr)
, mSharedHandle(aSharedHandle)
, mShareType(aShareType)
{
}
SharedTextureHostOGL::~SharedTextureHostOGL()
{
// If need to deallocate textures, call DeallocateSharedData() before
// the destructor
}
gl::GLContext*
SharedTextureHostOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
bool
SharedTextureHostOGL::Lock()
{
if (!mCompositor) {
return false;
}
if (!mTextureSource) {
// XXX on android GetSharedHandleDetails can call into Java which we'd
// rather not do from the compositor
GLContext::SharedHandleDetails handleDetails;
if (!gl()->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
NS_WARNING("Could not get shared handle details");
return false;
}
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
mTextureSource = new SharedTextureSourceOGL(nullptr, // Compositor
mSharedHandle,
handleDetails.mTextureFormat,
handleDetails.mTarget,
wrapMode,
mShareType,
mSize,
handleDetails.mTextureTransform);
}
return true;
}
void
SharedTextureHostOGL::Unlock()
{
if (!mTextureSource) {
return;
}
mTextureSource->DetachSharedHandle();
}
void
SharedTextureHostOGL::SetCompositor(Compositor* aCompositor)
{
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
if (mTextureSource) {
mTextureSource->SetCompositor(glCompositor);
}
}
gfx::SurfaceFormat
SharedTextureHostOGL::GetFormat() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetFormat();
}
TextureImageDeprecatedTextureHostOGL::~TextureImageDeprecatedTextureHostOGL()
{
MOZ_COUNT_DTOR(TextureImageDeprecatedTextureHostOGL);
@ -551,6 +794,7 @@ YCbCrDeprecatedTextureHostOGL::Lock()
return true;
}
TiledDeprecatedTextureHostOGL::~TiledDeprecatedTextureHostOGL()
{
DeleteTextures();
@ -730,6 +974,17 @@ void GrallocDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor)
mCompositor = glCompositor;
}
gfx::SurfaceFormat
GrallocDeprecatedTextureHostOGL::GetFormat() const
{
if (mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
return gfx::FORMAT_R8G8B8A8;
}
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D);
return mFormat;
}
void
GrallocDeprecatedTextureHostOGL::DeleteTextures()
{
@ -849,12 +1104,6 @@ GrallocDeprecatedTextureHostOGL::Unlock()
// Lock/Unlock is done internally when binding the gralloc buffer to a gl texture
}
gfx::SurfaceFormat
GrallocDeprecatedTextureHostOGL::GetFormat() const
{
return mFormat;
}
void
GrallocDeprecatedTextureHostOGL::SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator)
{
@ -923,7 +1172,7 @@ SharedDeprecatedTextureHostOGL::GetAsSurface() {
nsRefPtr<gfxImageSurface> surf = IsValid() ?
mGL->GetTexImage(GetTextureHandle(),
false,
GetTextureFormat())
GetFormat())
: nullptr;
return surf.forget();
}
@ -933,7 +1182,7 @@ SurfaceStreamHostOGL::GetAsSurface() {
nsRefPtr<gfxImageSurface> surf = IsValid() ?
mGL->GetTexImage(mTextureHandle,
false,
GetTextureFormat())
GetFormat())
: nullptr;
return surf.forget();
}
@ -943,7 +1192,7 @@ TiledDeprecatedTextureHostOGL::GetAsSurface() {
nsRefPtr<gfxImageSurface> surf = IsValid() ?
mGL->GetTexImage(mTextureHandle,
false,
GetTextureFormat())
GetFormat())
: nullptr;
return surf.forget();
}
@ -964,7 +1213,7 @@ GrallocDeprecatedTextureHostOGL::GetAsSurface() {
nsRefPtr<gfxImageSurface> surf = IsValid() ?
gl()->GetTexImage(tex,
false,
GetTextureFormat())
GetFormat())
: nullptr;
return surf.forget();
}

View File

@ -38,32 +38,10 @@ class CompositorOGL;
* sequence as simple as possible.
*/
/**
* TextureSourceOGL provides the necessary API for CompositorOGL to composite
* a TextureSource.
*/
class TextureSourceOGL
{
public:
virtual bool IsValid() const = 0;
virtual void BindTexture(GLenum aTextureUnit) = 0;
virtual void ReleaseTexture() = 0;
virtual gfx::IntSize GetSize() const = 0;
virtual gfx::SurfaceFormat GetTextureFormat() const {
MOZ_CRASH("unhandled texture format");
}
// TODO: Noone's implementing this anymore, should see if we need this.
virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
virtual GLenum GetWrapMode() const = 0;// { return LOCAL_GL_CLAMP_TO_EDGE; } // default
virtual gfx3DMatrix GetTextureTransform() { return gfx3DMatrix(); }
virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
};
inline ShaderProgramType
GetProgramTypeForTexture(const DeprecatedTextureHost *aDeprecatedTextureHost)
{
switch (aDeprecatedTextureHost->GetFormat()) {
GetProgramTypeForSurfaceFormat(gfx::SurfaceFormat aFormat)
{
switch (aFormat) {
case gfx::FORMAT_B8G8R8A8:
return BGRALayerProgramType;;
case gfx::FORMAT_B8G8R8X8:
@ -77,6 +55,248 @@ GetProgramTypeForTexture(const DeprecatedTextureHost *aDeprecatedTextureHost)
}
}
inline ShaderProgramType
GetProgramTypeForTexture(const DeprecatedTextureHost *aDeprecatedTextureHost)
{
return GetProgramTypeForSurfaceFormat(aDeprecatedTextureHost->GetFormat());
}
/**
* TextureSourceOGL provides the necessary API for CompositorOGL to composite
* a TextureSource.
*/
class TextureSourceOGL
{
public:
virtual bool IsValid() const = 0;
virtual void BindTexture(GLenum aTextureUnit) = 0;
/**
* Unbind this texture
* XXX - "Release" is confusing, should be called UnbindTexture instead.
*/
virtual void ReleaseTexture() = 0;
virtual gfx::IntSize GetSize() const = 0;
virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
virtual gfx::SurfaceFormat GetFormat() const = 0;
virtual GLenum GetWrapMode() const = 0;
virtual gfx3DMatrix GetTextureTransform() { return gfx3DMatrix(); }
virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
};
/**
* A TextureSource backed by a TextureImage.
*
* Depending on the underlying TextureImage, may support texture tiling, so
* make sure to check AsTileIterator() and use the texture accordingly.
*
* This TextureSource can be used without a TextureHost and manage it's own
* GL texture(s).
*/
class TextureImageTextureSourceOGL : public DataTextureSource
, public TextureSourceOGL
, public TileIterator
{
public:
TextureImageTextureSourceOGL(gl::GLContext* aGL, bool aAllowTiling = true)
: mGL(aGL)
, mAllowTiling(aAllowTiling)
, mIterating(false)
{}
// DataTextureSource
virtual bool Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
nsIntRegion* aDestRegion = nullptr,
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE;
// TextureSource
virtual void DeallocateDeviceData() MOZ_OVERRIDE
{
mTexImage = nullptr;
SetUpdateSerial(0);
}
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; }
virtual void ReleaseTexture() MOZ_OVERRIDE
{
mTexImage->ReleaseTexture();
}
virtual GLenum GetWrapMode() const MOZ_OVERRIDE
{
return mTexImage->GetWrapMode();
}
// TileIterator
virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return this; }
virtual void BeginTileIteration() MOZ_OVERRIDE
{
mTexImage->BeginTileIteration();
mIterating = true;
}
virtual void EndTileIteration() MOZ_OVERRIDE
{
mIterating = false;
}
virtual nsIntRect GetTileRect() MOZ_OVERRIDE
{
return mTexImage->GetTileRect();
}
virtual size_t GetTileCount() MOZ_OVERRIDE
{
return mTexImage->GetTileCount();
}
virtual bool NextTile() MOZ_OVERRIDE
{
return mTexImage->NextTile();
}
protected:
nsRefPtr<gl::TextureImage> mTexImage;
gl::GLContext* mGL;
bool mAllowTiling;
bool mIterating;
};
/**
* A texture source meant for use with SharedTextureHostOGL.
*
* It does not own any GL texture, and attaches its shared handle to one of
* the compositor's temporary textures when binding.
*
* The shared texture handle is owned by the TextureHost.
*/
class SharedTextureSourceOGL : public NewTextureSource
, public TextureSourceOGL
{
public:
typedef gl::GLContext::SharedTextureShareType SharedTextureShareType;
SharedTextureSourceOGL(CompositorOGL* aCompositor,
gl::SharedTextureHandle aHandle,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
GLenum aWrapMode,
SharedTextureShareType aShareType,
gfx::IntSize aSize,
const gfx3DMatrix& aTexTransform);
virtual TextureSourceOGL* AsSourceOGL() { return this; }
virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
virtual bool IsValid() const MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE { return mTextureTransform; }
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; }
virtual void ReleaseTexture() MOZ_OVERRIDE {}
// SharedTextureSource doesn't own any gl texture
virtual void DeallocateDeviceData() {}
void DetachSharedHandle();
void SetCompositor(CompositorOGL* aCompositor);
gl::GLContext* gl() const;
protected:
gfx3DMatrix mTextureTransform;
gfx::IntSize mSize;
CompositorOGL* mCompositor;
gl::SharedTextureHandle mSharedHandle;
gfx::SurfaceFormat mFormat;
SharedTextureShareType mShareType;
GLenum mTextureTarget;
GLenum mWrapMode;
};
/**
* A TextureHost for shared GL Textures
*
* Most of the logic actually happens in SharedTextureSourceOGL.
*/
class SharedTextureHostOGL : public TextureHost
{
public:
SharedTextureHostOGL(uint64_t aID,
TextureFlags aFlags,
gl::GLContext::SharedTextureShareType aShareType,
gl::SharedTextureHandle aSharedhandle,
gfx::IntSize aSize,
bool inverted);
virtual ~SharedTextureHostOGL();
// SharedTextureHostOGL doesn't own any GL texture
virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
virtual bool Lock() MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE
{
return mTextureSource;
}
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
{
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
gl::GLContext* gl() const;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "SharedTextureHostOGL"; }
#endif
protected:
gfx::IntSize mSize;
CompositorOGL* mCompositor;
gl::SharedTextureHandle mSharedHandle;
gl::GLContext::SharedTextureShareType mShareType;
RefPtr<SharedTextureSourceOGL> mTextureSource;
};
/**
* DeprecatedTextureHost implementation using a TextureImage as the underlying texture.
*/
@ -148,11 +368,6 @@ public:
gfx::IntSize GetSize() const MOZ_OVERRIDE;
gfx::SurfaceFormat GetTextureFormat() const MOZ_OVERRIDE
{
return GetFormat();
}
GLenum GetWrapMode() const MOZ_OVERRIDE
{
return mTexture->GetWrapMode();
@ -201,6 +416,11 @@ public:
return mTexture->NextTile();
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return DeprecatedTextureHost::GetFormat();
}
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "TextureImageDeprecatedTextureHostOGL"; }
#endif
@ -211,7 +431,6 @@ protected:
bool mIterating;
};
/**
* DeprecatedTextureHost implementation for YCbCr images in the OpenGL backend.
*
@ -285,6 +504,10 @@ public:
{
return mTexImage->GetWrapMode();
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return gfx::FORMAT_A8;
}
};
// TextureSource implementation
@ -321,6 +544,7 @@ private:
gl::GLContext* mGL;
};
class SharedDeprecatedTextureHostOGL : public DeprecatedTextureHost
, public TextureSourceOGL
{
@ -351,6 +575,11 @@ public:
return mTextureHandle;
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return DeprecatedTextureHost::GetFormat();
}
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
bool IsValid() const MOZ_OVERRIDE { return !!mSharedHandle; }
@ -368,11 +597,6 @@ public:
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; }
virtual void SetWrapMode(GLenum aMode) { mWrapMode = aMode; }
gfx::SurfaceFormat GetTextureFormat() const MOZ_OVERRIDE
{
return mFormat;
}
virtual GLenum GetTextureTarget() const MOZ_OVERRIDE
{
return mTextureTarget;
@ -438,6 +662,11 @@ public:
return mTextureHandle;
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return DeprecatedTextureHost::GetFormat();
}
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
bool IsValid() const MOZ_OVERRIDE { return true; }
@ -455,11 +684,6 @@ public:
mWrapMode = aMode;
}
gfx::SurfaceFormat GetTextureFormat() const MOZ_OVERRIDE
{
return mFormat;
}
gfx::IntSize GetSize() const MOZ_OVERRIDE {
return mSize;
}
@ -474,8 +698,9 @@ public:
mGL->fActiveTexture(activetex);
mGL->fBindTexture(mTextureTarget, mTextureHandle);
}
void ReleaseTexture() MOZ_OVERRIDE {
}
void ReleaseTexture() MOZ_OVERRIDE {}
GLuint GetTextureID() { return mTextureHandle; }
ContentType GetContentType() {
return (mFormat == gfx::FORMAT_B8G8R8A8) ?
@ -526,6 +751,11 @@ public:
virtual bool Lock() MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE {}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return DeprecatedTextureHost::GetFormat();
}
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
virtual bool IsValid() const MOZ_OVERRIDE { return true; }
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
@ -540,11 +770,6 @@ public:
return mSize;
}
gfx::SurfaceFormat GetTextureFormat() const MOZ_OVERRIDE
{
return GetFormat();
}
virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
nsIntRegion* aRegion = nullptr)
{ MOZ_ASSERT(false, "Tiles should not use this path"); }
@ -605,14 +830,7 @@ public:
return mGraphicBuffer.get() ? gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight()) : gfx::IntSize(0, 0);
}
gfx::SurfaceFormat GetTextureFormat() const MOZ_OVERRIDE
{
if (mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
return gfx::FORMAT_R8G8B8A8;
}
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D);
return mFormat;
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
GLenum GetWrapMode() const MOZ_OVERRIDE
{
@ -635,8 +853,6 @@ public:
void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
void ReleaseTexture() MOZ_OVERRIDE {}
virtual gfx::SurfaceFormat GetFormat() const;
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE
{
return this;

View File

@ -54,6 +54,11 @@ inline Size ToSize(const gfxSize &aSize)
return Size(Float(aSize.width), Float(aSize.height));
}
inline IntSize ToIntSize(const gfxIntSize &aSize)
{
return IntSize(aSize.width, aSize.height);
}
inline Filter ToFilter(gfxPattern::GraphicsFilter aFilter)
{
switch (aFilter) {

View File

@ -255,6 +255,13 @@ gfxPlatform::gfxPlatform()
mOpenTypeSVGEnabled = UNINITIALIZED_VALUE;
mBidiNumeralOption = UNINITIALIZED_VALUE;
mLayersPreferMemoryOverShmem =
XRE_GetProcessType() == GeckoProcessType_Default &&
Preferences::GetBool("layers.prefer-memory-over-shmem", true);
mLayersUseDeprecated =
Preferences::GetBool("layers.use-deprecated-textures", true);
uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
uint32_t contentMask = 0;
InitBackendPrefs(canvasMask, contentMask);
@ -503,6 +510,12 @@ gfxPlatform::~gfxPlatform()
#endif
}
bool
gfxPlatform::PreferMemoryOverShmem() const {
MOZ_ASSERT(!CompositorParent::IsInCompositorThread());
return mLayersPreferMemoryOverShmem;
}
already_AddRefed<gfxASurface>
gfxPlatform::CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType)

View File

@ -556,6 +556,14 @@ public:
static bool DrawLayerBorders();
static bool DrawFrameCounter();
/**
* Returns true if we should use raw memory to send data to the compositor
* rather than using shmems.
*
* This method should not be called from the compositor thread.
*/
bool PreferMemoryOverShmem() const;
bool UseDeprecatedTextures() const { return mLayersUseDeprecated; }
protected:
gfxPlatform();
@ -659,6 +667,8 @@ private:
mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder;
bool mWidgetUpdateFlashing;
uint32_t mOrientationSyncMillis;
bool mLayersPreferMemoryOverShmem;
bool mLayersUseDeprecated;
};
#endif /* GFX_PLATFORM_H */

View File

@ -16,6 +16,7 @@
#endif
#include "mozilla/Util.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/StandardInteger.h"
#include "nsID.h"
@ -721,6 +722,24 @@ struct ParamTraits<nsIntPoint>
}
};
template<>
struct ParamTraits<mozilla::gfx::IntSize>
{
typedef mozilla::gfx::IntSize paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.width);
WriteParam(msg, param.height);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->width) &&
ReadParam(msg, iter, &result->height));
}
};
template<>
struct ParamTraits<nsIntRect>
{
@ -1190,6 +1209,13 @@ struct ParamTraits<mozilla::layers::CompositableType>
mozilla::layers::BUFFER_COUNT>
{};
template <>
struct ParamTraits<mozilla::gfx::SurfaceFormat>
: public EnumSerializer<mozilla::gfx::SurfaceFormat,
mozilla::gfx::FORMAT_B8G8R8A8,
mozilla::gfx::FORMAT_UNKNOWN>
{};
} /* namespace IPC */
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

View File

@ -4056,6 +4056,9 @@ pref("layers.async-video.enabled",false);
// Whether to disable acceleration for all widgets.
pref("layers.acceleration.disabled", false);
// Whether to use the deprecated texture architecture rather than the new one.
pref("layers.use-deprecated-textures", true);
// Whether to force acceleration on, ignoring blacklists.
#ifdef ANDROID
// bug 838603 -- on Android, accidentally blacklisting OpenGL layers
@ -4080,6 +4083,8 @@ pref("layers.offmainthreadcomposition.enabled", false);
pref("layers.offmainthreadcomposition.testing.enabled", false);
// Whether to animate simple opacity and transforms on the compositor
pref("layers.offmainthreadcomposition.async-animations", false);
// Whether to prefer normal memory over shared memory. Ignored with cross-process compositing
pref("layers.prefer-memory-over-shmem", true);
#ifdef MOZ_X11
#ifdef MOZ_WIDGET_GTK2