mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 858914 - New texture classes + OGL backend (preffed off). r=bas, nrc
This commit is contained in:
parent
ea15a7a7de
commit
2b6a0c31a2
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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]; }
|
||||
|
129
gfx/layers/ImageDataSerializer.cpp
Normal file
129
gfx/layers/ImageDataSerializer.cpp
Normal 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
|
73
gfx/layers/ImageDataSerializer.h
Normal file
73
gfx/layers/ImageDataSerializer.h
Normal 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
|
@ -215,7 +215,7 @@ AppendToString(nsACString& s, TextureFlags flags,
|
||||
AppendFlag(ForceSingleTile);
|
||||
AppendFlag(AllowRepeat);
|
||||
AppendFlag(NewTile);
|
||||
AppendFlag(HostRelease);
|
||||
AppendFlag(TEXTURE_DEALLOCATE_HOST);
|
||||
|
||||
#undef AppendFlag
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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(),
|
||||
|
@ -34,6 +34,10 @@ public:
|
||||
virtual ~ClientCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientCanvasLayer);
|
||||
if (mCanvasClient) {
|
||||
mCanvasClient->Detach();
|
||||
mCanvasClient = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -27,6 +27,10 @@ public:
|
||||
}
|
||||
virtual ~ClientThebesLayer()
|
||||
{
|
||||
if (mContentClient) {
|
||||
mContentClient->Detach();
|
||||
mContentClient = nullptr;
|
||||
}
|
||||
MOZ_COUNT_DTOR(ClientThebesLayer);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ CanvasLayerComposite::~CanvasLayerComposite()
|
||||
}
|
||||
|
||||
void CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
|
||||
mImageHost = static_cast<ImageHost*>(aHost);
|
||||
mImageHost = aHost;
|
||||
}
|
||||
|
||||
Layer*
|
||||
|
@ -63,7 +63,7 @@ protected:
|
||||
#endif
|
||||
|
||||
private:
|
||||
RefPtr<ImageHost> mImageHost;
|
||||
RefPtr<CompositableHost> mImageHost;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -55,7 +55,7 @@ protected:
|
||||
#endif
|
||||
|
||||
private:
|
||||
RefPtr<ImageHost> mImageHost;
|
||||
RefPtr<CompositableHost> mImageHost;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ContentHost.h"
|
||||
#include "ClientTiledThebesLayer.h" // for BasicTiledLayerBuffer
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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(®ion);
|
||||
} else {
|
||||
// no region means invalidate the entire surface
|
||||
texture->Updated(nullptr);
|
||||
}
|
||||
compositable->UseTextureHost(texture);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
MOZ_ASSERT(false, "bad type");
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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&,
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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: {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user