Backed out 4 changesets (bug 991028) for nonunified bustage

CLOSED TREE

Backed out changeset 147581a518c3 (bug 991028)
Backed out changeset e5bacc566e58 (bug 991028)
Backed out changeset 6dc852777a4d (bug 991028)
Backed out changeset 780bec5571b9 (bug 991028)
This commit is contained in:
Phil Ringnalda 2014-04-06 21:21:38 -07:00
Родитель 2a7484aa1d
Коммит c213611c51
37 изменённых файлов: 1146 добавлений и 116 удалений

Просмотреть файл

@ -17,7 +17,6 @@
#include "AudioChannelFormat.h"
#include <mozilla/Monitor.h>
#include "mozilla/layers/GrallocTextureClient.h"
using namespace mozilla;
using namespace mozilla::gfx;
@ -257,9 +256,9 @@ void
ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
{
// Get graphic buffer.
GrallocTextureClientOGL* client =
static_cast<GrallocTextureClientOGL*>(aSource->GetTextureClient(nullptr));
sp<GraphicBuffer> graphicBuffer = client->GetGraphicBuffer();
SurfaceDescriptor handle = aSource->GetSurfaceDescriptor();
SurfaceDescriptorGralloc gralloc = handle.get_SurfaceDescriptorGralloc();
sp<GraphicBuffer> graphicBuffer = GrallocBufferActor::GetFrom(gralloc);
int pixelFormat = graphicBuffer->getPixelFormat();
// Only support NV21 (from camera) or YV12 (from HW decoder output) for now.

Просмотреть файл

@ -6,7 +6,6 @@
#include "Layers.h"
#include "ImageTypes.h"
#include "ImageContainer.h"
#include "mozilla/layers/GrallocTextureClient.h"
#include "nsMemory.h"
#include "mtransport/runnable_utils.h"
@ -654,9 +653,9 @@ MediaEngineWebRTCVideoSource::OnTakePictureComplete(uint8_t* aData, uint32_t aLe
void
MediaEngineWebRTCVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) {
layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(aImage);
layers::GrallocTextureClientOGL* client =
static_cast<layers::GrallocTextureClientOGL*>(nativeImage->GetTextureClient(nullptr));
android::sp<android::GraphicBuffer> graphicBuffer = client->GetGraphicBuffer();
layers::SurfaceDescriptor handle = nativeImage->GetSurfaceDescriptor();
layers::SurfaceDescriptorGralloc grallocHandle = handle.get_SurfaceDescriptorGralloc();
android::sp<android::GraphicBuffer> graphicBuffer = layers::GrallocBufferActor::GetFrom(grallocHandle);
void *pMem = nullptr;
uint32_t size = aWidth * aHeight * 3 / 2;

Просмотреть файл

@ -89,7 +89,6 @@ public:
{
Validate();
}
};
} // namespace layers

Просмотреть файл

@ -14,8 +14,12 @@ namespace layers {
/**
* Drawing with a mask requires a mask surface and a transform.
* Sometimes the mask surface is a direct gfxASurface, but other times
* it's a SurfaceDescriptor. For SurfaceDescriptor, we need to use a
* scoped AutoOpenSurface to get a gfxASurface for the
* SurfaceDescriptor.
*
* This helper class manages the gfxASurface
* This helper class manages the gfxASurface-or-SurfaceDescriptor
* logic.
*/
class MOZ_STACK_CLASS AutoMaskData {
@ -33,6 +37,9 @@ public:
void Construct(const gfx::Matrix& aTransform,
gfxASurface* aSurface);
void Construct(const gfx::Matrix& aTransform,
const SurfaceDescriptor& aSurface);
/** The returned surface can't escape the scope of |this|. */
gfxASurface* GetSurface();
const gfx::Matrix& GetTransform();
@ -42,6 +49,7 @@ private:
gfx::Matrix mTransform;
nsRefPtr<gfxASurface> mSurface;
Maybe<AutoOpenSurface> mSurfaceOpener;
AutoMaskData(const AutoMaskData&) MOZ_DELETE;
AutoMaskData& operator=(const AutoMaskData&) MOZ_DELETE;

Просмотреть файл

@ -5,6 +5,7 @@
#include "BasicCompositor.h"
#include "TextureHostBasic.h"
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/Effects.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "nsIWidget.h"

Просмотреть файл

@ -53,7 +53,8 @@ public:
virtual void Paint(DrawTarget* aDT, Layer* aMaskLayer) MOZ_OVERRIDE;
virtual bool GetAsSurface(gfxASurface** aSurface);
virtual bool GetAsSurface(gfxASurface** aSurface,
SurfaceDescriptor* aDescriptor);
virtual TemporaryRef<SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
protected:
@ -133,7 +134,8 @@ BasicImageLayer::GetAndPaintCurrentImage(DrawTarget* aTarget,
}
bool
BasicImageLayer::GetAsSurface(gfxASurface** aSurface)
BasicImageLayer::GetAsSurface(gfxASurface** aSurface,
SurfaceDescriptor* aDescriptor)
{
if (!mContainer) {
return false;

Просмотреть файл

@ -117,7 +117,8 @@ public:
* return false if a surface cannot be created. If true is
* returned, only one of |aSurface| or |aDescriptor| is valid.
*/
virtual bool GetAsSurface(gfxASurface** aSurface)
virtual bool GetAsSurface(gfxASurface** aSurface,
SurfaceDescriptor* aDescriptor)
{ return false; }
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }

Просмотреть файл

@ -27,11 +27,23 @@ AutoMaskData::Construct(const gfx::Matrix& aTransform,
mSurface = aSurface;
}
void
AutoMaskData::Construct(const gfx::Matrix& aTransform,
const SurfaceDescriptor& aSurface)
{
MOZ_ASSERT(!IsConstructed());
mTransform = aTransform;
mSurfaceOpener.construct(OPEN_READ_ONLY, aSurface);
}
gfxASurface*
AutoMaskData::GetSurface()
{
MOZ_ASSERT(IsConstructed());
return mSurface.get();
if (mSurface) {
return mSurface.get();
}
return mSurfaceOpener.ref().Get();
}
const gfx::Matrix&
@ -44,7 +56,7 @@ AutoMaskData::GetTransform()
bool
AutoMaskData::IsConstructed()
{
return !!mSurface;
return !!mSurface || !mSurfaceOpener.empty();
}
bool
@ -52,14 +64,19 @@ GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData)
{
if (aMaskLayer) {
nsRefPtr<gfxASurface> surface;
SurfaceDescriptor descriptor;
if (static_cast<BasicImplData*>(aMaskLayer->ImplData())
->GetAsSurface(getter_AddRefs(surface)) &&
surface) {
->GetAsSurface(getter_AddRefs(surface), &descriptor) &&
(surface || IsSurfaceDescriptorValid(descriptor))) {
Matrix transform;
Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform();
DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
aMaskData->Construct(transform, surface);
if (surface) {
aMaskData->Construct(transform, surface);
} else {
aMaskData->Construct(transform, descriptor);
}
return true;
}
}

Просмотреть файл

@ -11,6 +11,7 @@
#include "ReadbackLayer.h" // for ReadbackLayer
#include "gfxASurface.h" // for gfxASurface
#include "gfxContext.h" // for gfxContext, etc
#include "ipc/AutoOpenSurface.h" // for AutoOpenSurface
#include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_STACK_CLASS
#include "mozilla/Maybe.h" // for Maybe
#include "nsAutoPtr.h" // for nsRefPtr

Просмотреть файл

@ -7,6 +7,7 @@
#include "CompositorChild.h" // for CompositorChild
#include "GeckoProfiler.h" // for PROFILER_LABEL
#include "gfxASurface.h" // for gfxASurface, etc
#include "ipc/AutoOpenSurface.h" // for AutoOpenSurface
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Hal.h"
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
@ -288,10 +289,10 @@ ClientLayerManager::MakeSnapshotIfRequired()
// it through |outSnapshot|, but if it doesn't, it's
// responsible for freeing |snapshot|.
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(snapshot);
mShadowTarget->GetDrawTarget()->CopySurface(surf,
IntRect(0, 0, bounds.Size().width, bounds.Size().height),
IntPoint(0, 0));
AutoOpenSurface opener(OPEN_READ_ONLY, snapshot);
gfxASurface* source = opener.Get();
mShadowTarget->DrawSurface(source, source->GetSize());
}
if (IsSurfaceDescriptorValid(snapshot)) {
mForwarder->DestroySharedSurface(&snapshot);

Просмотреть файл

@ -572,16 +572,14 @@ WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
}
static void
FillSurface(DrawTarget* aDT, const nsIntRegion& aRegion,
FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
const nsIntPoint& aOffset, const gfxRGBA& aColor)
{
nsIntRegionRectIterator iter(aRegion);
const nsIntRect* r;
while ((r = iter.Next()) != nullptr) {
aDT->FillRect(Rect(r->x - aOffset.x, r->y - aOffset.y,
r->width, r->height),
ColorPattern(ToColor(aColor)));
}
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
gfxUtils::ClipToRegion(ctx, aRegion);
ctx->SetColor(aColor);
ctx->Paint();
}
RotatedContentBuffer::PaintState
@ -801,19 +799,22 @@ ContentClientIncremental::BorrowDrawTargetForPainting(ThebesLayer* aLayer,
// if it wants more to be repainted than we request.
if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
nsIntRegion drawRegionCopy = aPaintState.mRegionToDraw;
RefPtr<DrawTarget> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
RefPtr<DrawTarget> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw);
nsRefPtr<gfxASurface> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
nsRefPtr<gfxASurface> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw);
if (onBlack && onWhite) {
NS_ASSERTION(aPaintState.mRegionToDraw == drawRegionCopy,
"BeginUpdate should always modify the draw region in the same way!");
FillSurface(onBlack, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
FillSurface(onWhite, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlack, onWhite);
RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize().ToIntSize());
RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize().ToIntSize());
mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
} else {
mLoanedDrawTarget = nullptr;
}
} else {
mLoanedDrawTarget = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw);
nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw);
mLoanedDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize().ToIntSize());
}
if (!mLoanedDrawTarget) {
NS_WARNING("unable to get context for update");
@ -841,6 +842,8 @@ ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw,
bool aDidSelfCopy)
{
if (IsSurfaceDescriptorValid(mUpdateDescriptor)) {
ShadowLayerForwarder::CloseDescriptor(mUpdateDescriptor);
mForwarder->UpdateTextureIncremental(this,
TextureFront,
mUpdateDescriptor,
@ -850,6 +853,8 @@ ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw,
mUpdateDescriptor = SurfaceDescriptor();
}
if (IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)) {
ShadowLayerForwarder::CloseDescriptor(mUpdateDescriptorOnWhite);
mForwarder->UpdateTextureIncremental(this,
TextureOnWhiteFront,
mUpdateDescriptorOnWhite,
@ -861,7 +866,7 @@ ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw,
}
TemporaryRef<DrawTarget>
already_AddRefed<gfxASurface>
ContentClientIncremental::GetUpdateSurface(BufferType aType,
const nsIntRegion& aUpdateRegion)
{
@ -878,6 +883,9 @@ ContentClientIncremental::GetUpdateSurface(BufferType aType,
return nullptr;
}
nsRefPtr<gfxASurface> tmpASurface =
ShadowLayerForwarder::OpenDescriptor(OPEN_READ_WRITE, desc);
if (aType == BUFFER_BLACK) {
MOZ_ASSERT(!IsSurfaceDescriptorValid(mUpdateDescriptor));
mUpdateDescriptor = desc;
@ -887,7 +895,7 @@ ContentClientIncremental::GetUpdateSurface(BufferType aType,
mUpdateDescriptorOnWhite = desc;
}
return GetDrawTargetForDescriptor(desc, gfx::BackendType::COREGRAPHICS);
return tmpASurface.forget();
}
}

Просмотреть файл

@ -459,7 +459,7 @@ private:
}
TemporaryRef<gfx::DrawTarget> GetUpdateSurface(BufferType aType,
already_AddRefed<gfxASurface> GetUpdateSurface(BufferType aType,
const nsIntRegion& aUpdateRegion);
TextureInfo mTextureInfo;

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsAString.h"
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsString.h" // for nsAutoCString
#include "ipc/AutoOpenSurface.h" // for AutoOpenSurface
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
namespace mozilla {
@ -621,12 +622,19 @@ ContentHostIncremental::TextureUpdateRequest::Execute(ContentHostIncremental* aH
IntPoint offset = ToIntPoint(-mUpdated.GetBounds().TopLeft());
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(mDescriptor);
AutoOpenSurface surf(OPEN_READ_ONLY, mDescriptor);
nsRefPtr<gfxImageSurface> thebesSurf = surf.GetAsImage();
RefPtr<DataSourceSurface> sourceSurf =
gfx::Factory::CreateWrappingDataSourceSurface(thebesSurf->Data(),
thebesSurf->Stride(),
ToIntSize(thebesSurf->GetSize()),
ImageFormatToSurfaceFormat(thebesSurf->Format()));
if (mTextureId == TextureFront) {
aHost->mSource->Update(surf, &mUpdated, &offset);
aHost->mSource->Update(sourceSurf, &mUpdated, &offset);
} else {
aHost->mSourceOnWhite->Update(surf, &mUpdated, &offset);
aHost->mSourceOnWhite->Update(sourceSurf, &mUpdated, &offset);
}
}

Просмотреть файл

@ -216,6 +216,8 @@ public:
return mCompositor;
}
bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
/**
* LayerManagerComposite provides sophisticated debug overlays
* that can request a next frame.

Просмотреть файл

@ -146,6 +146,7 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TSurfaceDescriptorMemory:
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSharedTextureDescriptor:
case SurfaceDescriptor::TSurfaceDescriptorGralloc:
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
case SurfaceDescriptor::TSurfaceStreamDescriptor:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);

Просмотреть файл

@ -8,6 +8,7 @@
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "Effects.h"
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"

Просмотреть файл

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/PLayerTransaction.h"
#include "gfxImageSurface.h"

Просмотреть файл

@ -3,6 +3,7 @@
* 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 "ipc/AutoOpenSurface.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/RefPtr.h"

Просмотреть файл

@ -8,6 +8,7 @@
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "Effects.h"
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "gfxWindowsPlatform.h"
#include "gfx2DGlue.h"

Просмотреть файл

@ -9,6 +9,8 @@
// typedefs conflicts.
#include "mozilla/ArrayUtils.h"
#include "ipc/AutoOpenSurface.h"
#include "ThebesLayerD3D9.h"
#include "gfxPlatform.h"

Просмотреть файл

@ -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 mozilla_layers_AutoOpenSurface_h
#define mozilla_layers_AutoOpenSurface_h 1
#include "base/basictypes.h"
#include "gfxASurface.h"
#include "mozilla/layers/PLayerTransaction.h"
#include "ShadowLayers.h"
namespace mozilla {
namespace layers {
/**
* Some surface types can be fairly expensive to open. This helper
* tries to put off opening surfaces as long as it can, until
* ahsolutely necessary. And after being forced to open, it remembers
* the mapping so it doesn't need to be redone.
*/
class MOZ_STACK_CLASS AutoOpenSurface
{
public:
/** |aDescriptor| must be valid while AutoOpenSurface is
* in scope. */
AutoOpenSurface(OpenMode aMode, const SurfaceDescriptor& aDescriptor);
~AutoOpenSurface();
/**
* These helpers do not necessarily need to open the descriptor to
* return an answer.
*/
gfxContentType ContentType();
gfxImageFormat ImageFormat();
gfx::IntSize Size();
/** This can't escape the scope of AutoOpenSurface. */
gfxASurface* Get();
/**
* This can't escape the scope of AutoOpenSurface.
*
* This method is currently just a convenience wrapper around
* gfxASurface::GetAsImageSurface() --- it returns a valid surface
* exactly when this->Get()->GetAsImageSurface() would. Clients
* that need guaranteed (fast) ImageSurfaces should allocate the
* underlying descriptor with capability MAP_AS_IMAGE_SURFACE, in
* which case this helper is guaranteed to succeed.
*/
gfxImageSurface* GetAsImage();
private:
SurfaceDescriptor mDescriptor;
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<gfxImageSurface> mSurfaceAsImage;
OpenMode mMode;
AutoOpenSurface(const AutoOpenSurface&) MOZ_DELETE;
AutoOpenSurface& operator=(const AutoOpenSurface&) MOZ_DELETE;
};
} // namespace layers
} // namespace mozilla
#endif // ifndef mozilla_layers_AutoOpenSurface_h

Просмотреть файл

@ -42,6 +42,7 @@ class PTextureChild;
*/
class CompositableForwarder : public ISurfaceAllocator
{
friend class AutoOpenSurface;
public:
CompositableForwarder()
@ -105,6 +106,16 @@ public:
virtual void UpdatePictureRect(CompositableClient* aCompositable,
const nsIntRect& aRect) = 0;
/**
* The specified layer is destroying its buffers.
* |aBackBufferToDestroy| is deallocated when this transaction is
* posted to the parent. During the parent-side transaction, the
* shadow is told to destroy its front buffer. This can happen when
* a new front/back buffer pair have been created because of a layer
* resize, e.g.
*/
virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) = 0;
/**
* Tell the CompositableHost on the compositor side to remove the texture.
* This function does not delete the TextureHost corresponding to the

Просмотреть файл

@ -9,6 +9,7 @@
#include <stdint.h> // for uint64_t
#include <map> // for _Rb_tree_iterator, etc
#include <utility> // for pair
#include "AutoOpenSurface.h" // for AutoOpenSurface
#include "LayerTransactionParent.h" // for LayerTransactionParent
#include "RenderTrace.h" // for RenderTraceLayers
#include "base/message_loop.h" // for MessageLoop
@ -312,7 +313,12 @@ bool
CompositorParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
SurfaceDescriptor* aOutSnapshot)
{
RefPtr<DrawTarget> target = GetDrawTargetForDescriptor(aInSnapshot, gfx::BackendType::CAIRO);
AutoOpenSurface opener(OPEN_READ_WRITE, aInSnapshot);
gfx::IntSize size = opener.Size();
// XXX CreateDrawTargetForSurface will always give us a Cairo surface, we can
// do better if AutoOpenSurface uses Moz2D directly.
RefPtr<DrawTarget> target =
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(opener.Get(), size);
ForceComposeToTarget(target);
*aOutSnapshot = aInSnapshot;
return true;

Просмотреть файл

@ -20,8 +20,6 @@
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "mozilla/ipc/Shmem.h"
#include "mozilla/layers/ImageDataSerializer.h"
#ifdef DEBUG
#include "prenv.h"
#endif
@ -59,39 +57,25 @@ ISurfaceAllocator::Finalize()
ShrinkShmemSectionHeap();
}
static inline uint8_t*
GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor, size_t& aSize)
bool
ISurfaceAllocator::AllocSharedImageSurface(const gfx::IntSize& aSize,
gfxContentType aContent,
gfxSharedImageSurface** aBuffer)
{
MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor));
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorShmem ||
aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorMemory);
if (aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorShmem) {
Shmem shmem(aDescriptor.get_SurfaceDescriptorShmem().data());
aSize = shmem.Size<uint8_t>();
return shmem.get<uint8_t>();
} else {
const SurfaceDescriptorMemory& image = aDescriptor.get_SurfaceDescriptorMemory();
aSize = std::numeric_limits<size_t>::max();
return reinterpret_cast<uint8_t*>(image.data());
}
}
mozilla::ipc::SharedMemory::SharedMemoryType shmemType = OptimalShmemType();
gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent);
TemporaryRef<gfx::DrawTarget>
GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend)
{
size_t size;
uint8_t* data = GetAddressFromDescriptor(aDescriptor, size);
ImageDataDeserializer image(data, size);
return image.GetAsDrawTarget(aBackend);
}
nsRefPtr<gfxSharedImageSurface> back =
gfxSharedImageSurface::CreateUnsafe(this,
gfx::ThebesIntSize(aSize),
format,
shmemType);
if (!back)
return false;
TemporaryRef<gfx::DataSourceSurface>
GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor)
{
size_t size;
uint8_t* data = GetAddressFromDescriptor(aDescriptor, size);
ImageDataDeserializer image(data, size);
return image.GetAsSurface();
*aBuffer = nullptr;
back.swap(*aBuffer);
return true;
}
bool
@ -108,11 +92,20 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
gfx::SurfaceFormat format =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
size_t size = ImageDataSerializer::ComputeMinBufferSize(aSize, format);
if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
uint8_t *data = new (std::nothrow) uint8_t[size];
bool tryPlatformSurface = true;
#ifdef DEBUG
tryPlatformSurface = !PR_GetEnv("MOZ_LAYERS_FORCE_SHMEM_SURFACES");
#endif
if (tryPlatformSurface &&
PlatformAllocSurfaceDescriptor(aSize, aContent, aCaps, aBuffer)) {
return true;
}
if (XRE_GetProcessType() == GeckoProcessType_Default) {
gfxImageFormat format =
gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent);
int32_t stride = gfxASurface::FormatStrideForWidth(format, aSize.width);
uint8_t *data = new (std::nothrow) uint8_t[stride * aSize.height];
if (!data) {
return false;
}
@ -120,32 +113,30 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
#ifdef XP_MACOSX
// Workaround a bug in Quartz where drawing an a8 surface to another a8
// surface with OPERATOR_SOURCE still requires the destination to be clear.
if (format == SurfaceFormat::A8) {
memset(data, 0, size);
if (format == gfxImageFormat::A8) {
memset(data, 0, stride * aSize.height);
}
#endif
*aBuffer = SurfaceDescriptorMemory((uintptr_t)data, format);
} else {
mozilla::ipc::SharedMemory::SharedMemoryType shmemType = OptimalShmemType();
mozilla::ipc::Shmem shmem;
if (!AllocUnsafeShmem(size, shmemType, &shmem)) {
return false;
}
*aBuffer = SurfaceDescriptorShmem(shmem, format);
*aBuffer = MemoryImage((uintptr_t)data, aSize, stride, format);
return true;
}
uint8_t* data = GetAddressFromDescriptor(*aBuffer, size);
ImageDataSerializer serializer(data, size);
serializer.InitializeBufferInfo(aSize, format);
nsRefPtr<gfxSharedImageSurface> buffer;
if (!AllocSharedImageSurface(aSize, aContent,
getter_AddRefs(buffer))) {
return false;
}
*aBuffer = buffer->GetShmem();
return true;
}
/* static */ bool
ISurfaceAllocator::IsShmem(SurfaceDescriptor* aSurface)
{
return aSurface && (aSurface->type() == SurfaceDescriptor::TSurfaceDescriptorShmem);
return aSurface && (aSurface->type() == SurfaceDescriptor::TShmem ||
aSurface->type() == SurfaceDescriptor::TYCbCrImage ||
aSurface->type() == SurfaceDescriptor::TRGBImage);
}
void
@ -158,13 +149,26 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
if (!IPCOpen()) {
return;
}
if (PlatformDestroySharedSurface(aSurface)) {
return;
}
switch (aSurface->type()) {
case SurfaceDescriptor::TSurfaceDescriptorShmem:
DeallocShmem(aSurface->get_SurfaceDescriptorShmem().data());
case SurfaceDescriptor::TShmem:
DeallocShmem(aSurface->get_Shmem());
break;
case SurfaceDescriptor::TSurfaceDescriptorMemory:
GfxMemoryImageReporter::WillFree((uint8_t*)aSurface->get_SurfaceDescriptorMemory().data());
delete [] (uint8_t*)aSurface->get_SurfaceDescriptorMemory().data();
case SurfaceDescriptor::TYCbCrImage:
DeallocShmem(aSurface->get_YCbCrImage().data());
break;
case SurfaceDescriptor::TRGBImage:
DeallocShmem(aSurface->get_RGBImage().data());
break;
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
case SurfaceDescriptor::TSurfaceDescriptorDIB:
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
break;
case SurfaceDescriptor::TMemoryImage:
GfxMemoryImageReporter::WillFree((uint8_t*)aSurface->get_MemoryImage().data());
delete [] (uint8_t*)aSurface->get_MemoryImage().data();
break;
case SurfaceDescriptor::Tnull_t:
case SurfaceDescriptor::T__None:
@ -175,6 +179,17 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
*aSurface = SurfaceDescriptor();
}
#if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfx::IntSize&,
gfxContentType,
uint32_t,
SurfaceDescriptor*)
{
return false;
}
#endif
// XXX - We should actually figure out the minimum shmem allocation size on
// a certain platform and use that.
const uint32_t sShmemPageSize = 4096;

Просмотреть файл

@ -40,9 +40,6 @@ namespace mozilla {
namespace ipc {
class Shmem;
}
namespace gfx {
class DataSourceSurface;
}
namespace layers {
@ -71,9 +68,6 @@ mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType();
bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface);
bool IsSurfaceDescriptorOwned(const SurfaceDescriptor& aDescriptor);
bool ReleaseOwnedSurfaceDescriptor(const SurfaceDescriptor& aDescriptor);
TemporaryRef<gfx::DrawTarget> GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend);
TemporaryRef<gfx::DataSourceSurface> GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor);
/**
* An interface used to create and destroy surfaces that are shared with the
* Compositor process (using shmem, or gralloc, or other platform specific memory)
@ -137,6 +131,9 @@ public:
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) = 0;
// was AllocBuffer
virtual bool AllocSharedImageSurface(const gfx::IntSize& aSize,
gfxContentType aContent,
gfxSharedImageSurface** aBuffer);
virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer);
@ -177,6 +174,12 @@ public:
protected:
virtual bool IsOnCompositorSide() const = 0;
bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
virtual bool PlatformAllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer);
virtual ~ISurfaceAllocator();

Просмотреть файл

@ -276,6 +276,11 @@ public:
const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE {
NS_RUNTIMEABORT("should not be called");
}
virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) MOZ_OVERRIDE
{
NS_RUNTIMEABORT("should not be called");
}
// ISurfaceAllocator

Просмотреть файл

@ -66,11 +66,63 @@ struct NewSurfaceDescriptorGralloc {
IntSize size;
};
// XXX - soon to be removed
struct SurfaceDescriptorGralloc {
PGrallocBuffer buffer;
/**
* android::GraphicBuffer has a size information. But there are cases
* that GraphicBuffer's size and actual video's size are different.
* Extra size member is necessary. See Bug 850566.
*/
IntSize size;
/**
* We can have one source producing gralloc buffers and sharing them
* with another source that may also produce its own gralloc buffers.
* This happens for camera preview buffers sent to video code. When
* that happens, the producer can mark the buffer as "external" to
* prevent its consumer from mistakenly freeing the buffer.
*/
bool external;
/**
* This gralloc 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.
*/
bool isRBSwapped;
};
struct SurfaceStreamDescriptor {
SurfaceStreamHandle handle;
bool yflip;
};
// XXX - can be removed as soon as DeprecatedImageClientSingle is removed
struct YCbCrImage {
Shmem data;
uint64_t owner;
};
// XXX remove RGBImage (see bug 847914)
struct RGBImage {
Shmem data;
nsIntRect picture;
gfxImageFormat rgbFormat;
uint64_t owner;
};
struct MemoryImage {
uintptr_t data;
IntSize size;
uint32_t stride;
gfxImageFormat format;
};
/**
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
*/
@ -98,6 +150,11 @@ union SurfaceDescriptor {
SurfaceStreamDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
YCbCrImage; // XXX - deprecated
SurfaceDescriptorGralloc; // XXX - deprecated
Shmem; // XXX - deprecated
RGBImage; // XXX - deprecated
MemoryImage; // XXX - deprecated
null_t;
};

Просмотреть файл

@ -18,12 +18,77 @@ using namespace mozilla::gl;
namespace mozilla {
namespace layers {
// Platform-specific shadow-layers interfaces. See ShadowLayers.h.
// D3D10 doesn't need all these yet.
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfx::IntSize&,
gfxContentType,
uint32_t,
SurfaceDescriptor*)
{
return false;
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode,
const SurfaceDescriptor&)
{
return nullptr;
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor&)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor&,
OpenMode,
gfxContentType*,
gfxASurface**)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor&,
OpenMode,
gfx::IntSize*,
gfxASurface**)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
const SurfaceDescriptor&,
OpenMode,
gfxImageFormat*,
gfxASurface**)
{
return false;
}
bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{
}
bool
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
/*static*/ bool
LayerManagerComposite::SupportsDirectTexturing()
{

Просмотреть файл

@ -342,6 +342,29 @@ LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
// Nothing to be done for gralloc.
}
bool
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aSurface->type()) {
return false;
}
// we should have either a bufferParent or bufferChild
// depending on whether we're on the parent or child side.
PGrallocBufferParent* gbp =
aSurface->get_SurfaceDescriptorGralloc().bufferParent();
if (gbp) {
unused << PGrallocBufferParent::Send__delete__(gbp);
} else {
PGrallocBufferChild* gbc =
aSurface->get_SurfaceDescriptorGralloc().bufferChild();
DeallocGrallocBuffer(gbc);
}
*aSurface = SurfaceDescriptor();
return true;
}
//-----------------------------------------------------------------------------
// Child process
@ -376,15 +399,206 @@ ShadowLayerForwarder::DeallocGrallocBuffer(PGrallocBufferChild* aChild)
PGrallocBufferChild::Send__delete__(aChild);
}
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
if (aSize.width <= 0 || aSize.height <= 0) {
return false;
}
#if ANDROID_VERSION <= 15
// Adreno 200 fails to render gralloc textures with width < 64
// or with height < 32.
if (aSize.width < 64 || aSize.height < 32) {
return false;
}
#endif
PROFILER_LABEL("ShadowLayerForwarder", "PlatformAllocSurfaceDescriptor");
// Gralloc buffers are efficiently mappable as gfxImageSurface, so
// no need to check |aCaps & MAP_AS_IMAGE_SURFACE|.
MaybeMagicGrallocBufferHandle handle;
PGrallocBufferChild* gc;
bool defaultRBSwap;
if (PixelFormatForContentType(aContent) == android::PIXEL_FORMAT_UNKNOWN) {
return false;
}
if (aCaps & USING_GL_RENDERING_ONLY) {
gc = AllocGrallocBuffer(aSize,
PixelFormatForContentType(aContent),
GraphicBuffer::USAGE_HW_RENDER |
GraphicBuffer::USAGE_HW_TEXTURE,
&handle);
// If you're allocating for USING_GL_RENDERING_ONLY, then we don't flag
// this for RB swap.
defaultRBSwap = false;
} else {
gc = AllocGrallocBuffer(aSize,
PixelFormatForContentType(aContent),
GraphicBuffer::USAGE_SW_READ_OFTEN |
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
GraphicBuffer::USAGE_HW_TEXTURE,
&handle);
// But if you're allocating for non-GL-only rendering, we flag for
// RB swap to preserve old behaviour and proper interaction with
// cairo.
defaultRBSwap = true;
}
if (!gc) {
NS_ERROR("GrallocBufferConstructor failed by returned null");
return false;
} else if (handle.Tnull_t == handle.type()) {
NS_ERROR("GrallocBufferConstructor failed by returning handle with type Tnull_t");
PGrallocBufferChild::Send__delete__(gc);
return false;
}
GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(gc);
gba->InitFromHandle(handle.get_MagicGrallocBufferHandle());
*aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize,
/* external */ false,
defaultRBSwap);
return true;
}
//-----------------------------------------------------------------------------
// Both processes
/*static*/ sp<GraphicBuffer>
GrallocBufferActor::GetFrom(const SurfaceDescriptorGralloc& aDescriptor)
{
GrallocBufferActor* gba = nullptr;
if (PGrallocBufferChild* child = aDescriptor.bufferChild()) {
gba = static_cast<GrallocBufferActor*>(child);
} else if (PGrallocBufferParent* parent = aDescriptor.bufferParent()) {
gba = static_cast<GrallocBufferActor*>(parent);
}
return gba->mGraphicBuffer;
}
android::GraphicBuffer*
GrallocBufferActor::GetGraphicBuffer()
{
return mGraphicBuffer.get();
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
const SurfaceDescriptor& aSurface)
{
PROFILER_LABEL("ShadowLayerForwarder", "PlatformOpenDescriptor");
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aSurface.type()) {
return nullptr;
}
sp<GraphicBuffer> buffer =
GrallocBufferActor::GetFrom(aSurface.get_SurfaceDescriptorGralloc());
uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN;
if (OPEN_READ_WRITE == aMode) {
usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
}
void *vaddr;
DebugOnly<status_t> status = buffer->lock(usage, &vaddr);
// If we fail to lock, we'll just end up aborting anyway.
MOZ_ASSERT(status == OK);
gfx::IntSize size = aSurface.get_SurfaceDescriptorGralloc().size();
gfxImageFormat format = ImageFormatForPixelFormat(buffer->getPixelFormat());
long pixelStride = buffer->getStride();
long byteStride = pixelStride * gfxASurface::BytePerPixelFromFormat(format);
nsRefPtr<gfxASurface> surf =
new gfxImageSurface((unsigned char*)vaddr,
gfx::ThebesIntSize(size),
byteStride,
format);
return surf->CairoStatus() ? nullptr : surf.forget();
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxContentType* aContent,
gfxASurface** aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) {
return false;
}
sp<GraphicBuffer> buffer =
GrallocBufferActor::GetFrom(aDescriptor.get_SurfaceDescriptorGralloc());
*aContent = ContentTypeFromPixelFormat(buffer->getPixelFormat());
return true;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfx::IntSize* aSize,
gfxASurface** aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) {
return false;
}
sp<GraphicBuffer> buffer =
GrallocBufferActor::GetFrom(aDescriptor.get_SurfaceDescriptorGralloc());
*aSize = aDescriptor.get_SurfaceDescriptorGralloc().size();
return true;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxImageFormat* aImageFormat,
gfxASurface** aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) {
return false;
}
sp<GraphicBuffer> buffer =
GrallocBufferActor::GetFrom(aDescriptor.get_SurfaceDescriptorGralloc());
*aImageFormat = ImageFormatForPixelFormat(buffer->getPixelFormat());
return true;
}
/*static*/ bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aSurface->type()) {
return false;
}
PGrallocBufferChild* gbp =
aSurface->get_SurfaceDescriptorGralloc().bufferChild();
PGrallocBufferChild::Send__delete__(gbp);
*aSurface = SurfaceDescriptor();
return true;
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
{
PROFILER_LABEL("ShadowLayerForwarder", "PlatformCloseDescriptor");
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) {
return false;
}
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aDescriptor);
DebugOnly<status_t> status = buffer->unlock();
// If we fail to unlock, we'll subsequently fail to lock and end up aborting anyway.
MOZ_ASSERT(status == OK);
return true;
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{

Просмотреть файл

@ -24,6 +24,7 @@ namespace mozilla {
namespace layers {
class MaybeMagicGrallocBufferHandle;
class SurfaceDescriptorGralloc;
class TextureHost;
/**
@ -76,6 +77,9 @@ public:
static PGrallocBufferChild*
Create();
static android::sp<GraphicBuffer>
GetFrom(const SurfaceDescriptorGralloc& aDescriptor);
// used only for hacky fix in gecko 23 for bug 862324
// see bug 865908 about fixing this.
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

Просмотреть файл

@ -21,6 +21,77 @@ using namespace mozilla::gl;
namespace mozilla {
namespace layers {
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
return false;
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
const SurfaceDescriptor& aSurface)
{
if (aSurface.type() == SurfaceDescriptor::TShmem) {
return gfxSharedQuartzSurface::Open(aSurface.get_Shmem());
} else if (aSurface.type() == SurfaceDescriptor::TMemoryImage) {
const MemoryImage& image = aSurface.get_MemoryImage();
gfxImageFormat format
= static_cast<gfxImageFormat>(image.format());
nsRefPtr<gfxASurface> surf =
new gfxQuartzSurface((unsigned char*)image.data(),
gfx::ThebesIntSize(image.size()),
image.stride(),
format);
return surf.forget();
}
return nullptr;
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxContentType* aContent,
gfxASurface** aSurface)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfx::IntSize* aSize,
gfxASurface** aSurface)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
const SurfaceDescriptor&,
OpenMode,
gfxImageFormat*,
gfxASurface**)
{
return false;
}
bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
return false;
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{
@ -31,6 +102,12 @@ LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
{
}
bool
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
/*static*/ bool
LayerManagerComposite::SupportsDirectTexturing()
{

Просмотреть файл

@ -63,6 +63,17 @@ GetXRenderPictFormatFromId(Display* aDisplay, PictFormat aFormatId)
return XRenderFindFormat(aDisplay, PictFormatID, &tmplate, 0);
}
static bool
TakeAndDestroyXlibSurface(SurfaceDescriptor* aSurface)
{
nsRefPtr<gfxXlibSurface> surf =
aSurface->get_SurfaceDescriptorX11().OpenForeign();
surf->TakePixmap();
*aSurface = SurfaceDescriptor();
// the Pixmap is destroyed when |surf| goes out of scope
return true;
}
SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf)
: mId(aSurf->XDrawable())
, mSize(aSurf->GetSize().ToIntSize())
@ -104,6 +115,95 @@ SurfaceDescriptorX11::OpenForeign() const
return surf->CairoStatus() ? nullptr : surf.forget();
}
bool
ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
if (!UsingXCompositing()) {
// If we're not using X compositing, we're probably compositing on
// the client side, in which case X surfaces would just slow
// things down. Use Shmem instead.
return false;
}
if (MAP_AS_IMAGE_SURFACE & aCaps) {
// We can't efficiently map pixmaps as gfxImageSurface, in
// general. Fall back on Shmem.
return false;
}
gfxPlatform* platform = gfxPlatform::GetPlatform();
nsRefPtr<gfxASurface> buffer =
platform->CreateOffscreenSurface(aSize, aContent);
if (!buffer ||
buffer->GetType() != gfxSurfaceType::Xlib) {
NS_ERROR("creating Xlib front/back surfaces failed!");
return false;
}
gfxXlibSurface* bufferX = static_cast<gfxXlibSurface*>(buffer.get());
// Release Pixmap ownership to the layers model
bufferX->ReleasePixmap();
*aBuffer = SurfaceDescriptorX11(bufferX);
return true;
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
const SurfaceDescriptor& aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorX11 != aSurface.type()) {
return nullptr;
}
return aSurface.get_SurfaceDescriptorX11().OpenForeign();
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
{
// XIDs don't need to be "closed".
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxContentType* aContent,
gfxASurface** aSurface)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfx::IntSize* aSize,
gfxASurface** aSurface)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
const SurfaceDescriptor&,
OpenMode,
gfxImageFormat*,
gfxASurface**)
{
return false;
}
bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorX11 != aSurface->type()) {
return false;
}
return TakeAndDestroyXlibSurface(aSurface);
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{
@ -135,5 +235,14 @@ LayerManagerComposite::SupportsDirectTexturing()
return false;
}
bool
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
if (SurfaceDescriptor::TSurfaceDescriptorX11 != aSurface->type()) {
return false;
}
return TakeAndDestroyXlibSurface(aSurface);
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -8,6 +8,7 @@
#include "ShadowLayers.h"
#include <set> // for _Rb_tree_const_iterator, etc
#include <vector> // for vector
#include "AutoOpenSurface.h" // for AutoOpenSurface, etc
#include "GeckoProfiler.h" // for PROFILER_LABEL
#include "ISurfaceAllocator.h" // for IsSurfaceDescriptorValid
#include "Layers.h" // for Layer
@ -119,10 +120,21 @@ public:
NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?");
mMutants.insert(aLayer);
}
void AddBufferToDestroy(gfxSharedImageSurface* aBuffer)
{
return AddBufferToDestroy(aBuffer->GetShmem());
}
void AddBufferToDestroy(const SurfaceDescriptor& aBuffer)
{
NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?");
mDyingBuffers.AppendElement(aBuffer);
}
void End()
{
mCset.clear();
mPaints.clear();
mDyingBuffers.Clear();
mMutants.clear();
mOpen = false;
mSwapRequired = false;
@ -139,6 +151,7 @@ public:
EditVector mCset;
EditVector mPaints;
BufferArray mDyingBuffers;
ShadowableLayerSet mMutants;
nsIntRect mTargetBounds;
ScreenRotation mTargetRotation;
@ -235,6 +248,12 @@ ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef)
CreatedLayer<OpCreateRefLayer>(mTxn, aRef);
}
void
ShadowLayerForwarder::DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy)
{
mTxn->AddBufferToDestroy(aBackBufferToDestroy);
}
void
ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant)
{
@ -297,11 +316,11 @@ ShadowLayerForwarder::CheckSurfaceDescriptor(const SurfaceDescriptor* aDescripto
return;
}
if (aDescriptor->type() == SurfaceDescriptor::TSurfaceDescriptorShmem) {
const SurfaceDescriptorShmem& shmem = aDescriptor->get_SurfaceDescriptorShmem();
shmem.data().AssertInvariants();
if (aDescriptor->type() == SurfaceDescriptor::TShmem) {
const mozilla::ipc::Shmem& shmem = aDescriptor->get_Shmem();
shmem.AssertInvariants();
MOZ_ASSERT(mShadowManager &&
mShadowManager->IsTrackingSharedMemory(shmem.data().mSegment));
mShadowManager->IsTrackingSharedMemory(shmem.mSegment));
}
}
#endif
@ -437,6 +456,10 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers..."));
for (uint32_t i = 0; i < mTxn->mDyingBuffers.Length(); ++i) {
DestroySharedSurface(&mTxn->mDyingBuffers[i]);
}
MOZ_LAYERS_LOG(("[LayersForwarder] building transaction..."));
// We purposely add attribute-change ops to the final changeset
@ -577,6 +600,111 @@ ShadowLayerForwarder::IsSameProcess() const
return mShadowManager->OtherProcess() == kInvalidProcessHandle;
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::OpenDescriptor(OpenMode aMode,
const SurfaceDescriptor& aSurface)
{
nsRefPtr<gfxASurface> surf = PlatformOpenDescriptor(aMode, aSurface);
if (surf) {
return surf.forget();
}
switch (aSurface.type()) {
case SurfaceDescriptor::TShmem: {
surf = gfxSharedImageSurface::Open(aSurface.get_Shmem());
return surf.forget();
} case SurfaceDescriptor::TRGBImage: {
const RGBImage& rgb = aSurface.get_RGBImage();
gfxImageFormat rgbFormat
= static_cast<gfxImageFormat>(rgb.rgbFormat());
uint32_t stride = gfxASurface::BytesPerPixel(rgbFormat) * rgb.picture().width;
nsIntSize size(rgb.picture().width, rgb.picture().height);
surf = new gfxImageSurface(rgb.data().get<uint8_t>(),
size,
stride,
rgbFormat);
return surf.forget();
}
case SurfaceDescriptor::TMemoryImage: {
const MemoryImage& image = aSurface.get_MemoryImage();
gfxImageFormat format
= static_cast<gfxImageFormat>(image.format());
surf = new gfxImageSurface((unsigned char *)image.data(),
gfx::ThebesIntSize(image.size()),
image.stride(),
format);
return surf.forget();
}
default:
NS_ERROR("unexpected SurfaceDescriptor type!");
return nullptr;
}
}
/*static*/ gfxContentType
ShadowLayerForwarder::GetDescriptorSurfaceContentType(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxASurface** aSurface)
{
gfxContentType content;
if (PlatformGetDescriptorSurfaceContentType(aDescriptor, aMode,
&content, aSurface)) {
return content;
}
nsRefPtr<gfxASurface> surface = OpenDescriptor(aMode, aDescriptor);
content = surface->GetContentType();
surface.forget(aSurface);
return content;
}
/*static*/ gfx::IntSize
ShadowLayerForwarder::GetDescriptorSurfaceSize(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxASurface** aSurface)
{
gfx::IntSize size;
if (PlatformGetDescriptorSurfaceSize(aDescriptor, aMode, &size, aSurface)) {
return size;
}
nsRefPtr<gfxASurface> surface = OpenDescriptor(aMode, aDescriptor);
size = surface->GetSize().ToIntSize();
surface.forget(aSurface);
return size;
}
/*static*/ gfxImageFormat
ShadowLayerForwarder::GetDescriptorSurfaceImageFormat(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxASurface** aSurface)
{
gfxImageFormat format;
if (PlatformGetDescriptorSurfaceImageFormat(aDescriptor, aMode, &format, aSurface)) {
return format;
}
nsRefPtr<gfxASurface> surface = OpenDescriptor(aMode, aDescriptor);
NS_ENSURE_TRUE(surface, gfxImageFormat::Unknown);
nsRefPtr<gfxImageSurface> img = surface->GetAsImageSurface();
NS_ENSURE_TRUE(img, gfxImageFormat::Unknown);
format = img->Format();
NS_ASSERTION(format != gfxImageFormat::Unknown,
"ImageSurface RGB format should be known");
surface.forget(aSurface);
return format;
}
/*static*/ void
ShadowLayerForwarder::CloseDescriptor(const SurfaceDescriptor& aDescriptor)
{
PlatformCloseDescriptor(aDescriptor);
// There's no "close" needed for Shmem surfaces.
}
/**
* We bail out when we have no shadow manager. That can happen when the
* layer manager is created by the preallocated process.
@ -591,13 +719,140 @@ ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer)
#if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode,
const SurfaceDescriptor&)
{
return nullptr;
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor&)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor&,
OpenMode,
gfxContentType*,
gfxASurface**)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor&,
OpenMode,
gfx::IntSize*,
gfxASurface**)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
const SurfaceDescriptor&,
OpenMode,
gfxImageFormat*,
gfxASurface**)
{
return false;
}
bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{
}
bool
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
#endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
AutoOpenSurface::AutoOpenSurface(OpenMode aMode,
const SurfaceDescriptor& aDescriptor)
: mDescriptor(aDescriptor)
, mMode(aMode)
{
MOZ_ASSERT(IsSurfaceDescriptorValid(mDescriptor));
}
AutoOpenSurface::~AutoOpenSurface()
{
if (mSurface) {
mSurface = nullptr;
ShadowLayerForwarder::CloseDescriptor(mDescriptor);
}
}
gfxContentType
AutoOpenSurface::ContentType()
{
if (mSurface) {
return mSurface->GetContentType();
}
return ShadowLayerForwarder::GetDescriptorSurfaceContentType(
mDescriptor, mMode, getter_AddRefs(mSurface));
}
gfxImageFormat
AutoOpenSurface::ImageFormat()
{
if (mSurface) {
nsRefPtr<gfxImageSurface> img = mSurface->GetAsImageSurface();
if (img) {
gfxImageFormat format = img->Format();
NS_ASSERTION(format != gfxImageFormat::Unknown,
"ImageSurface RGB format should be known");
return format;
}
}
return ShadowLayerForwarder::GetDescriptorSurfaceImageFormat(
mDescriptor, mMode, getter_AddRefs(mSurface));
}
gfx::IntSize
AutoOpenSurface::Size()
{
if (mSurface) {
return mSurface->GetSize().ToIntSize();
}
return ShadowLayerForwarder::GetDescriptorSurfaceSize(
mDescriptor, mMode, getter_AddRefs(mSurface));
}
gfxASurface*
AutoOpenSurface::Get()
{
if (!mSurface) {
mSurface = ShadowLayerForwarder::OpenDescriptor(mMode, mDescriptor);
}
return mSurface.get();
}
gfxImageSurface*
AutoOpenSurface::GetAsImage()
{
if (!mSurfaceAsImage) {
mSurfaceAsImage = Get()->GetAsImageSurface();
}
return mSurfaceAsImage.get();
}
void
ShadowLayerForwarder::Connect(CompositableClient* aCompositable)
{

Просмотреть файл

@ -48,6 +48,7 @@ class PLayerTransactionParent;
class LayerTransactionChild;
class RefLayerComposite;
class ShadowableLayer;
class Shmem;
class ShmemTextureClient;
class SurfaceDescriptor;
class TextureClient;
@ -133,6 +134,7 @@ class Transaction;
class ShadowLayerForwarder : public CompositableForwarder
{
friend class AutoOpenSurface;
friend class ContentClientIncremental;
friend class ClientLayerManager;
@ -198,6 +200,16 @@ public:
void CreatedCanvasLayer(ShadowableLayer* aCanvas);
void CreatedRefLayer(ShadowableLayer* aRef);
/**
* The specified layer is destroying its buffers.
* |aBackBufferToDestroy| is deallocated when this transaction is
* posted to the parent. During the parent-side transaction, the
* shadow is told to destroy its front buffer. This can happen when
* a new front/back buffer pair have been created because of a layer
* resize, e.g.
*/
virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) MOZ_OVERRIDE;
/**
* At least one attribute of |aMutant| has changed, and |aMutant|
* needs to sync to its shadow layer. This initial implementation
@ -366,6 +378,9 @@ public:
static void PlatformSyncBeforeUpdate();
static already_AddRefed<gfxASurface>
OpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aSurface);
protected:
ShadowLayerForwarder();
@ -388,6 +403,61 @@ protected:
#endif
private:
/**
* Try to query the content type efficiently, but at worst map the
* surface and return it in *aSurface.
*/
static gfxContentType
GetDescriptorSurfaceContentType(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxASurface** aSurface);
/**
* It can be expensive to open a descriptor just to query its
* content type. If the platform impl can do this cheaply, it will
* set *aContent and return true.
*/
static bool
PlatformGetDescriptorSurfaceContentType(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxContentType* aContent,
gfxASurface** aSurface);
// (Same as above, but for surface size.)
static gfx::IntSize
GetDescriptorSurfaceSize(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxASurface** aSurface);
static bool
PlatformGetDescriptorSurfaceSize(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfx::IntSize* aSize,
gfxASurface** aSurface);
// And again, for the image format.
// This function will return gfxImageFormat::Unknown only if |aDescriptor|
// describes a non-ImageSurface.
static gfxImageFormat
GetDescriptorSurfaceImageFormat(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxASurface** aSurface);
static bool
PlatformGetDescriptorSurfaceImageFormat(const SurfaceDescriptor& aDescriptor,
OpenMode aMode,
gfxImageFormat* aContent,
gfxASurface** aSurface);
static already_AddRefed<gfxASurface>
PlatformOpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aDescriptor);
/**
* Make this descriptor unusable for gfxASurface clients. A
* private interface with AutoOpenSurface.
*/
static void
CloseDescriptor(const SurfaceDescriptor& aDescriptor);
static bool
PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor);
bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
Transaction* mTxn;
DiagnosticTypes mDiagnosticTypes;

Просмотреть файл

@ -36,7 +36,12 @@ public:
virtual void DeallocateSharedData(ISurfaceAllocator* allocator) MOZ_OVERRIDE
{
allocator->DeallocGrallocBuffer(mGrallocActor);
// We just need to wrap the actor in a SurfaceDescriptor because that's what
// ISurfaceAllocator uses as input, we don't care about the other parameters.
SurfaceDescriptor sd = SurfaceDescriptorGralloc(nullptr, mGrallocActor,
IntSize(0, 0),
false, false);
allocator->DestroySharedSurface(&sd);
mGrallocActor = nullptr;
}
@ -80,8 +85,16 @@ GrallocTextureClientOGL::~GrallocTextureClientOGL()
{
MOZ_COUNT_DTOR(GrallocTextureClientOGL);
if (ShouldDeallocateInDestructor()) {
// If the buffer has never been shared we must deallocate it or it would
// leak.
// We just need to wrap the actor in a SurfaceDescriptor because that's what
// ISurfaceAllocator uses as input, we don't care about the other parameters.
SurfaceDescriptor sd = SurfaceDescriptorGralloc(nullptr, mGrallocActor,
IntSize(0, 0),
false, false);
ISurfaceAllocator* allocator = GetAllocator();
allocator->DeallocGrallocBuffer(mGrallocActor);
allocator->DestroySharedSurface(&sd);
}
}

Просмотреть файл

@ -17,6 +17,7 @@
#include "gfx2DGlue.h" // for ContentForFormat, etc
#include "gfxImageSurface.h" // for gfxImageSurface
#include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper
#include "ipc/AutoOpenSurface.h" // for AutoOpenSurface
#include "mozilla/gfx/2D.h" // for DataSourceSurface
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL

Просмотреть файл

@ -25,7 +25,6 @@
#include "VideoUtils.h"
#ifdef MOZ_WIDGET_GONK
#include "GrallocImages.h"
#include "mozilla/layers/GrallocTextureClient.h"
#endif
#endif
@ -1113,10 +1112,10 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
#ifdef MOZ_WIDGET_GONK
if (format == ImageFormat::GRALLOC_PLANAR_YCBCR) {
layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(img);
layers::GrallocTextureClientOGL* client =
static_cast<layers::GrallocTextureClientOGL*>(nativeImage->GetTextureClient(nullptr));
layers::SurfaceDescriptor handle = nativeImage->GetSurfaceDescriptor();
layers::SurfaceDescriptorGralloc grallocHandle = handle.get_SurfaceDescriptorGralloc();
android::sp<android::GraphicBuffer> graphicBuffer = client->GetGraphicBuffer();
android::sp<android::GraphicBuffer> graphicBuffer = layers::GrallocBufferActor::GetFrom(grallocHandle);
void *basePtr;
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_MASK, &basePtr);
conduit->SendVideoFrame(static_cast<unsigned char*>(basePtr),