Bug 591687: Add new image type for IOSurfaces on Mac OS X. r=roc r=benwa a=blocking2.0betaN+

This commit is contained in:
Matt Woodrow 2011-02-12 11:02:08 -05:00
Родитель 52fa449634
Коммит c7b2e69359
8 изменённых файлов: 254 добавлений и 5 удалений

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

@ -42,6 +42,7 @@
#include "gfxPattern.h"
#include "nsThreadUtils.h"
#include "nsCoreAnimationSupport.h"
namespace mozilla {
namespace layers {
@ -95,7 +96,15 @@ public:
* manipulated on the main thread, since the underlying cairo surface
* is main-thread-only.
*/
CAIRO_SURFACE
CAIRO_SURFACE,
/**
* The MAC_IO_SURFACE format creates a MacIOSurfaceImage. This
* is only supported on Mac with OpenGL layers.
*
* It wraps an IOSurface object and binds it directly to a GL texture.
*/
MAC_IO_SURFACE
};
Format GetFormat() { return mFormat; }
@ -338,6 +347,25 @@ protected:
CairoImage(void* aImplData) : Image(aImplData, CAIRO_SURFACE) {}
};
#ifdef XP_MACOSX
class THEBES_API MacIOSurfaceImage : public Image {
public:
struct Data {
nsIOSurface* mIOSurface;
};
/**
* This can only be called on the main thread. It may add a reference
* to the surface (which will eventually be released on the main thread).
* The surface must not be modified after this call!!!
*/
virtual void SetData(const Data& aData) = 0;
protected:
MacIOSurfaceImage(void* aImplData) : Image(aImplData, MAC_IO_SURFACE) {}
};
#endif
}
}

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

@ -83,6 +83,12 @@ CPPSRCS = \
ThebesLayerOGL.cpp \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
CMMSRCS = \
MacIOSurfaceImageOGL.mm \
$(NULL)
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
ifdef MOZ_ENABLE_D3D9_LAYER
EXPORTS += \

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

@ -44,6 +44,7 @@
#include "gfxImageSurface.h"
#include "yuv_convert.h"
#include "GLContextProvider.h"
#include "MacIOSurfaceImageOGL.h"
using namespace mozilla::gl;
@ -218,6 +219,12 @@ ImageContainerOGL::CreateImage(const Image::Format *aFormats,
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
img = new CairoImageOGL(static_cast<LayerManagerOGL*>(mManager));
}
#ifdef XP_MACOSX
else if (aFormats[0] == Image::MAC_IO_SURFACE) {
img = new MacIOSurfaceImageOGL(static_cast<LayerManagerOGL*>(mManager));
}
#endif
return img.forget();
}
@ -319,7 +326,6 @@ ImageContainerOGL::GetCurrentSize()
return gfxIntSize(0,0);
}
return yuvImage->mSize;
}
if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
@ -328,6 +334,14 @@ ImageContainerOGL::GetCurrentSize()
return cairoImage->mSize;
}
#ifdef XP_MACOSX
if (mActiveImage->GetFormat() == Image::MAC_IO_SURFACE) {
MacIOSurfaceImageOGL *ioImage =
static_cast<MacIOSurfaceImageOGL*>(mActiveImage.get());
return ioImage->mSize;
}
#endif
return gfxIntSize(0,0);
}
@ -447,6 +461,37 @@ ImageLayerOGL::RenderLayer(int,
program->SetTextureUnit(0);
mOGLManager->BindAndDrawQuad(program);
#ifdef XP_MACOSX
} else if (image->GetFormat() == Image::MAC_IO_SURFACE) {
MacIOSurfaceImageOGL *ioImage =
static_cast<MacIOSurfaceImageOGL*>(image.get());
gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, ioImage->mTexture.GetTextureID());
ColorTextureLayerProgram *program =
mOGLManager->GetRGBARectLayerProgram();
program->Activate();
if (program->GetTexCoordMultiplierUniformLocation() != -1) {
// 2DRect case, get the multiplier right for a sampler2DRect
float f[] = { float(ioImage->mSize.width), float(ioImage->mSize.height) };
program->SetUniform(program->GetTexCoordMultiplierUniformLocation(),
2, f);
} else {
NS_ASSERTION(0, "no rects?");
}
program->SetLayerQuadRect(nsIntRect(0, 0,
ioImage->mSize.width,
ioImage->mSize.height));
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);
mOGLManager->BindAndDrawQuad(program);
gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
#endif
}
DEBUG_GL_ERROR_CHECK(gl());
@ -703,7 +748,6 @@ CairoImageOGL::SetData(const CairoImage::Data &aData)
tex);
}
#ifdef MOZ_IPC
ShadowImageLayerOGL::ShadowImageLayerOGL(LayerManagerOGL* aManager)

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

@ -240,7 +240,6 @@ public:
gl::ShaderProgramType mLayerProgram;
};
#ifdef MOZ_IPC
class ShadowImageLayerOGL : public ShadowImageLayer,
public LayerOGL

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

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_MACIOSURFACEIMAGEOGL_H
#define GFX_MACIOSURFACEIMAGEOGL_H
#ifdef XP_MACOSX
#include "nsCoreAnimationSupport.h"
namespace mozilla {
namespace layers {
class THEBES_API MacIOSurfaceImageOGL : public MacIOSurfaceImage
{
typedef mozilla::gl::GLContext GLContext;
public:
MacIOSurfaceImageOGL(LayerManagerOGL *aManager);
void SetData(const Data &aData);
GLTexture mTexture;
gfxIntSize mSize;
nsAutoPtr<nsIOSurface> mIOSurface;
};
} /* layers */
} /* mozilla */
#endif /* XP_MACOSX */
#endif /* GFX_MACIOSURFACEIMAGEOGL_H */

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

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Matt Woodrow <mwoodrow@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ImageLayerOGL.h"
#include "MacIOSurfaceImageOGL.h"
#include <AppKit/NSOpenGL.h>
#include "OpenGL/OpenGL.h"
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
MacIOSurfaceImageOGL::MacIOSurfaceImageOGL(LayerManagerOGL *aManager)
: MacIOSurfaceImage(nsnull), mSize(0, 0)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread to create a cairo image");
if (aManager) {
// Allocate texture now to grab a reference to the GLContext
GLContext *gl = aManager->glForResources();
mTexture.Allocate(gl);
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTexture.GetTextureID());
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MIN_FILTER,
LOCAL_GL_NEAREST);
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_TEXTURE_MAG_FILTER,
LOCAL_GL_NEAREST);
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
}
}
void
MacIOSurfaceImageOGL::SetData(const MacIOSurfaceImage::Data &aData)
{
mIOSurface = nsIOSurface::LookupSurface(aData.mIOSurface->GetIOSurfaceID());
mSize = gfxIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
GLContext *gl = mTexture.GetGLContext();
gl->MakeCurrent();
gl->fActiveTexture(LOCAL_GL_TEXTURE0);
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTexture.GetTextureID());
void *nativeCtx = gl->GetNativeData(GLContext::NativeGLContext);
NSOpenGLContext* nsCtx = (NSOpenGLContext*)nativeCtx;
mIOSurface->CGLTexImageIOSurface2D((CGLContextObj)[nsCtx CGLContextObj],
LOCAL_GL_RGBA, LOCAL_GL_BGRA,
LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV, 0);
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
}
} /* layers */
} /* mozilla */

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

@ -44,6 +44,7 @@
#import "ApplicationServices/ApplicationServices.h"
#include "nscore.h"
#include "gfxTypes.h"
#import <QuartzCore/QuartzCore.h>
// Get the system color space.
CGColorSpaceRef THEBES_API CreateSystemColorSpace();
@ -103,6 +104,9 @@ public:
size_t GetBytesPerRow();
void Lock();
void Unlock();
CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt,
GLenum internalFormat, GLenum format,
GLenum type, GLuint plane);
private:
friend class nsCARenderer;
CFTypeRef mIOSurfacePtr;

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

@ -323,7 +323,7 @@ nsIOSurface* nsIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID) {
nsIOSurface* ioSurface = new nsIOSurface(surfaceRef);
if (!ioSurface) {
::CFRelease(ioSurface);
::CFRelease(surfaceRef);
return nsnull;
}
return ioSurface;
@ -358,6 +358,19 @@ void nsIOSurface::Unlock() {
nsIOSurfaceLib::IOSurfaceUnlock(mIOSurfacePtr, READ_ONLY, NULL);
}
CGLError
nsIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctxt,
GLenum internalFormat, GLenum format,
GLenum type, GLuint plane)
{
return nsIOSurfaceLib::CGLTexImageIOSurface2D(ctxt,
GL_TEXTURE_RECTANGLE_ARB,
internalFormat,
GetWidth(), GetHeight(),
format, type,
mIOSurfacePtr, plane);
}
nsCARenderer::~nsCARenderer() {
Destroy();
}