зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
2a7484aa1d
Коммит
c213611c51
|
@ -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),
|
||||
|
|
Загрузка…
Ссылка в новой задаче