Bug 984437 - Backout for build bustage on a CLOSED TREE

This commit is contained in:
Nicolas Silva 2014-03-18 17:18:07 +01:00
parent 74fca13a7f
commit e454ee8ae8
6 changed files with 434 additions and 1 deletions

View File

@ -357,6 +357,14 @@ DeprecatedTextureHost::SwapTextures(const SurfaceDescriptor& aImage,
*aResult = *mBuffer;
}
*mBuffer = aImage;
// The following SetBuffer call was added in bug 912725 as a fix for the
// hacky fix introduced in gecko 23 for bug 862324.
// Note that it is a no-op in the generic case, but not for
// GrallocDeprecatedTextureHostOGL which overrides SetBuffer to make it
// register the TextureHost with the GrallocBufferActor.
// The reason why this SetBuffer calls is needed here is that just above we
// overwrote *mBuffer in place, so we need to tell the new mBuffer about this
// TextureHost.
SetBuffer(mBuffer, mDeAllocator);
}

View File

@ -761,7 +761,9 @@ public:
* retain a SurfaceDescriptor.
* Ownership of the SurfaceDescriptor passes to this.
*/
void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator);
// only made virtual to allow overriding in GrallocDeprecatedTextureHostOGL, for hacky fix in gecko 23 for bug 862324.
// see bug 865908 about fixing this.
virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator);
// used only for hacky fix in gecko 23 for bug 862324
// see bug 865908 about fixing this.

View File

@ -317,6 +317,11 @@ GrallocBufferActor::Create(const gfx::IntSize& aSize,
void GrallocBufferActor::ActorDestroy(ActorDestroyReason)
{
// used only for hacky fix for bug 862324
for (size_t i = 0; i < mDeprecatedTextureHosts.Length(); i++) {
mDeprecatedTextureHosts[i]->ForgetBuffer();
}
// Used only for hacky fix for bug 966446.
if (mTextureHost) {
mTextureHost->ForgetBufferActor();
@ -324,6 +329,21 @@ void GrallocBufferActor::ActorDestroy(ActorDestroyReason)
}
}
// used only for hacky fix for bug 862324
void GrallocBufferActor::AddDeprecatedTextureHost(DeprecatedTextureHost* aDeprecatedTextureHost)
{
mDeprecatedTextureHosts.AppendElement(aDeprecatedTextureHost);
}
// used only for hacky fix for bug 862324
void GrallocBufferActor::RemoveDeprecatedTextureHost(DeprecatedTextureHost* aDeprecatedTextureHost)
{
mDeprecatedTextureHosts.RemoveElement(aDeprecatedTextureHost);
// that should be the only occurence, otherwise we'd leak this TextureHost...
// assert that that's not happening.
MOZ_ASSERT(!mDeprecatedTextureHosts.Contains(aDeprecatedTextureHost));
}
void GrallocBufferActor::AddTextureHost(TextureHost* aTextureHost)
{
mTextureHost = aTextureHost;

View File

@ -85,6 +85,11 @@ public:
// see bug 865908 about fixing this.
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
// used only for hacky fix in gecko 23 for bug 862324
// see bug 865908 about fixing this.
void AddDeprecatedTextureHost(DeprecatedTextureHost* aDeprecatedTextureHost);
void RemoveDeprecatedTextureHost(DeprecatedTextureHost* aDeprecatedTextureHost);
void AddTextureHost(TextureHost* aTextureHost);
void RemoveTextureHost();

View File

@ -65,6 +65,10 @@ CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
if (aDeprecatedTextureHostFlags & TEXTURE_HOST_TILED) {
result = new TiledDeprecatedTextureHostOGL();
#ifdef MOZ_WIDGET_GONK
} else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorGralloc) {
result = new GrallocDeprecatedTextureHostOGL();
#endif
} else {
result = new TextureImageDeprecatedTextureHostOGL();
}
@ -922,6 +926,286 @@ TiledDeprecatedTextureHostOGL::Lock()
return true;
}
#ifdef MOZ_WIDGET_GONK
static gfx::SurfaceFormat
Deprecated_SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
bool swapRB = false)
{
switch (aFormat) {
case android::PIXEL_FORMAT_BGRA_8888:
return swapRB ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::B8G8R8A8;
case android::PIXEL_FORMAT_RGBA_8888:
return swapRB ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::R8G8B8A8;
case android::PIXEL_FORMAT_RGBX_8888:
return swapRB ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::R8G8B8X8;
case android::PIXEL_FORMAT_RGB_565:
return SurfaceFormat::R5G6B5;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YV12:
return SurfaceFormat::B8G8R8A8; // yup, use SurfaceFormat::B8G8R8A8 even though it's a YUV texture. This is an external texture.
default:
if (aFormat >= 0x100 && aFormat <= 0x1FF) {
// Reserved range for HAL specific formats.
return SurfaceFormat::B8G8R8A8;
} else {
// This is not super-unreachable, there's a bunch of hypothetical pixel
// formats we don't deal with.
// We only want to abort in debug builds here, since if we crash here
// we'll take down the compositor process and thus the phone. This seems
// like undesirable behaviour. We'd rather have a subtle artifact.
MOZ_ASSERT(false, "Unknown Android pixel format.");
return SurfaceFormat::UNKNOWN;
}
}
}
static GLenum
Deprecated_TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
{
switch (aFormat) {
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YV12:
return LOCAL_GL_TEXTURE_EXTERNAL;
case android::PIXEL_FORMAT_RGBA_8888:
case android::PIXEL_FORMAT_RGBX_8888:
case android::PIXEL_FORMAT_RGB_565:
return LOCAL_GL_TEXTURE_2D;
default:
if (aFormat >= 0x100 && aFormat <= 0x1FF) {
// Reserved range for HAL specific formats.
return LOCAL_GL_TEXTURE_EXTERNAL;
} else {
// This is not super-unreachable, there's a bunch of hypothetical pixel
// formats we don't deal with.
// We only want to abort in debug builds here, since if we crash here
// we'll take down the compositor process and thus the phone. This seems
// like undesirable behaviour. We'd rather have a subtle artifact.
MOZ_ASSERT(false, "Unknown Android pixel format.");
return LOCAL_GL_TEXTURE_EXTERNAL;
}
}
}
GrallocDeprecatedTextureHostOGL::GrallocDeprecatedTextureHostOGL()
: mCompositor(nullptr)
, mTextureTarget(0)
, mEGLImage(0)
, mIsRBSwapped(false)
{
}
void GrallocDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor)
{
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
if (mCompositor && !glCompositor) {
DeleteTextures();
}
mCompositor = glCompositor;
}
gfx::SurfaceFormat
GrallocDeprecatedTextureHostOGL::GetFormat() const
{
switch (mTextureTarget) {
case LOCAL_GL_TEXTURE_EXTERNAL: return gfx::SurfaceFormat::R8G8B8A8;
case LOCAL_GL_TEXTURE_2D: return mFormat;
default: return gfx::SurfaceFormat::UNKNOWN;
}
}
void
GrallocDeprecatedTextureHostOGL::DeleteTextures()
{
if (mEGLImage) {
if (gl()->MakeCurrent()) {
EGLImageDestroy(gl(), mEGLImage);
}
mEGLImage = EGL_NO_IMAGE;
}
}
// only used for hacky fix in gecko 23 for bug 862324
static void
AddDeprecatedTextureHostToGrallocBufferActor(DeprecatedTextureHost* aDeprecatedTextureHost, const SurfaceDescriptor* aSurfaceDescriptor)
{
if (aSurfaceDescriptor && IsSurfaceDescriptorValid(*aSurfaceDescriptor)) {
GrallocBufferActor* actor = static_cast<GrallocBufferActor*>(aSurfaceDescriptor->get_SurfaceDescriptorGralloc().bufferParent());
actor->AddDeprecatedTextureHost(aDeprecatedTextureHost);
}
}
static void
RemoveDeprecatedTextureHostFromGrallocBufferActor(DeprecatedTextureHost* aDeprecatedTextureHost, const SurfaceDescriptor* aSurfaceDescriptor)
{
if (aSurfaceDescriptor && IsSurfaceDescriptorValid(*aSurfaceDescriptor)) {
GrallocBufferActor* actor = static_cast<GrallocBufferActor*>(aSurfaceDescriptor->get_SurfaceDescriptorGralloc().bufferParent());
actor->RemoveDeprecatedTextureHost(aDeprecatedTextureHost);
}
}
void
GrallocDeprecatedTextureHostOGL::UpdateImpl(const SurfaceDescriptor& aImage,
nsIntRegion* aRegion,
nsIntPoint* aOffset)
{
SwapTexturesImpl(aImage, aRegion);
}
void
GrallocDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage,
nsIntRegion*)
{
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc);
const SurfaceDescriptorGralloc& desc = aImage.get_SurfaceDescriptorGralloc();
mGraphicBuffer = GrallocBufferActor::GetFrom(desc);
mIsRBSwapped = desc.isRBSwapped();
mFormat = Deprecated_SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat(),
mIsRBSwapped);
mTextureTarget = Deprecated_TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
GLuint tex = GetGLTexture();
// delete old EGLImage
DeleteTextures();
if (!gl()->MakeCurrent()) {
return;
}
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(mTextureTarget, tex);
// create new EGLImage
// create EGLImage during buffer swap could reduce the graphic driver's task
// during rendering.
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
}
gl::GLContext*
GrallocDeprecatedTextureHostOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
void GrallocDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
PROFILER_LABEL("Gralloc", "BindTexture");
/*
* The job of this function is to ensure that the texture is tied to the
* android::GraphicBuffer, so that texturing will source the GraphicBuffer.
*
* To this effect we create an EGLImage wrapping this GraphicBuffer,
* using CreateEGLImageForNativeBuffer, and then we tie this EGLImage to our
* texture using fEGLImageTargetTexture2D.
*
* We try to avoid re-creating the EGLImage everytime, by keeping it around
* as the mEGLImage member of this class.
*/
MOZ_ASSERT(gl());
if (!gl()->MakeCurrent()) {
return;
}
GLuint tex = GetGLTexture();
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, tex);
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
}
bool
GrallocDeprecatedTextureHostOGL::IsValid() const
{
return !!gl() && !!mGraphicBuffer.get();
}
GrallocDeprecatedTextureHostOGL::~GrallocDeprecatedTextureHostOGL()
{
DeleteTextures();
// only done for hacky fix in gecko 23 for bug 862324.
// make sure that if the GrallocBufferActor survives us, it doesn't keep a dangling
// pointer to us.
RemoveDeprecatedTextureHostFromGrallocBufferActor(this, mBuffer);
}
bool
GrallocDeprecatedTextureHostOGL::Lock()
{
// Lock/Unlock is done internally when binding the gralloc buffer to a gl texture
return IsValid();
}
void
GrallocDeprecatedTextureHostOGL::Unlock()
{
// Lock/Unlock is done internally when binding the gralloc buffer to a gl texture
}
void
GrallocDeprecatedTextureHostOGL::SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator)
{
MOZ_ASSERT(!mBuffer, "Will leak the old mBuffer");
if (aBuffer != mBuffer) {
// only done for hacky fix in gecko 23 for bug 862324.
// Doing this in SwapTextures is not enough, as the crash could occur right after SetBuffer.
RemoveDeprecatedTextureHostFromGrallocBufferActor(this, mBuffer);
AddDeprecatedTextureHostToGrallocBufferActor(this, aBuffer);
}
mBuffer = aBuffer;
mDeAllocator = aAllocator;
}
LayerRenderState
GrallocDeprecatedTextureHostOGL::GetRenderState()
{
if (mGraphicBuffer.get()) {
uint32_t flags = mFlags & TEXTURE_NEEDS_Y_FLIP ? LAYER_RENDER_STATE_Y_FLIPPED : 0;
/*
* The 32 bit format of gralloc buffer is created as RGBA8888 or RGBX888 by default.
* For software rendering (non-GL rendering), the content is drawn with BGRA
* or BGRX. Therefore, we need to pass the RBSwapped flag for HW composer to swap format.
*
* For GL rendering content, the content format is RGBA or RGBX which is the same as
* the pixel format of gralloc buffer and no need for the RBSwapped flag.
*/
if (mIsRBSwapped) {
flags |= LAYER_RENDER_STATE_FORMAT_RB_SWAP;
}
nsIntSize bufferSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight());
return LayerRenderState(mGraphicBuffer.get(),
bufferSize,
flags,
nullptr);
}
return LayerRenderState();
}
GLuint
GrallocDeprecatedTextureHostOGL::GetGLTexture()
{
mCompositableBackendData->SetCompositor(mCompositor);
return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture();
}
#endif // MOZ_WIDGET_GONK
TemporaryRef<gfx::DataSourceSurface>
TextureImageDeprecatedTextureHostOGL::GetAsSurface() {
RefPtr<gfx::DataSourceSurface> surf =
@ -939,5 +1223,26 @@ TiledDeprecatedTextureHostOGL::GetAsSurface() {
return surf.forget();
}
#ifdef MOZ_WIDGET_GONK
TemporaryRef<gfx::DataSourceSurface>
GrallocDeprecatedTextureHostOGL::GetAsSurface() {
if (!gl()->MakeCurrent()) {
return nullptr;
}
GLuint tex = GetGLTexture();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(mTextureTarget, tex);
if (!mEGLImage) {
mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
}
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
RefPtr<gfx::DataSourceSurface> surf =
IsValid() ? ReadBackSurface(gl(), tex, false, GetFormat())
: nullptr;
return surf.forget();
}
#endif // MOZ_WIDGET_GONK
} // namespace
} // namespace

View File

@ -654,6 +654,99 @@ private:
nsRefPtr<gl::GLContext> mGL;
};
#ifdef MOZ_WIDGET_GONK
// For direct texturing with gralloc buffers. The corresponding DeprecatedTextureClient is DeprecatedTextureClientShmem,
// which automatically gets gralloc when it can, in which case the compositor sees that the
// SurfaceDescriptor is gralloc, and decides to use a GrallocDeprecatedTextureHostOGL to do direct texturing,
// saving the cost of a texture upload.
class GrallocDeprecatedTextureHostOGL
: public DeprecatedTextureHost
, public TextureSourceOGL
{
public:
GrallocDeprecatedTextureHostOGL();
~GrallocDeprecatedTextureHostOGL();
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
virtual void UpdateImpl(const SurfaceDescriptor& aImage,
nsIntRegion* aRegion = nullptr,
nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
virtual bool Lock() MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE
{
return mGraphicBuffer.get() ? gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight()) : gfx::IntSize(0, 0);
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
GLenum GetWrapMode() const MOZ_OVERRIDE
{
return LOCAL_GL_CLAMP_TO_EDGE;
}
virtual GLenum GetTextureTarget() const MOZ_OVERRIDE
{
return mTextureTarget;
}
bool IsValid() const MOZ_OVERRIDE;
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
virtual const char* Name() { return "GrallocDeprecatedTextureHostOGL"; }
void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE
{
return this;
}
// only overridden for hacky fix in gecko 23 for bug 862324
// see bug 865908 about fixing this.
virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator) MOZ_OVERRIDE;
// used only for hacky fix in gecko 23 for bug 862324
virtual void ForgetBuffer()
{
if (mBuffer) {
// Intentionally don't destroy the actor held by mBuffer here.
// The point is that this is only called from GrallocBufferActor::ActorDestroy
// where we know that the actor is already being deleted.
// See bug 862324 comment 39.
delete mBuffer;
mBuffer = nullptr;
}
mGraphicBuffer = nullptr;
DeleteTextures();
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
GLuint GetGLTexture();
private:
gl::GLContext* gl() const;
void DeleteTextures();
RefPtr<CompositorOGL> mCompositor;
android::sp<android::GraphicBuffer> mGraphicBuffer;
GLenum mTextureTarget;
EGLImage mEGLImage;
//Set when the composer needs to swap RB pixels of gralloc buffer
bool mIsRBSwapped;
};
#endif
} // namespace
} // namespace