mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 882523 - Support OMTC on Mac in non-accelerated mode using OpenGL. r=nrc, r=mattwoodrow
This commit is contained in:
parent
e45a5e49e5
commit
d426585dce
@ -2026,21 +2026,23 @@ GLContext::BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
DataOffset(gfxImageSurface *aSurf, const nsIntPoint &aPoint)
|
||||
DataOffset(const nsIntPoint &aPoint, int32_t aStride, gfxASurface::gfxImageFormat aFormat)
|
||||
{
|
||||
unsigned int data = aPoint.y * aSurf->Stride();
|
||||
data += aPoint.x * gfxASurface::BytePerPixelFromFormat(aSurf->Format());
|
||||
unsigned int data = aPoint.y * aStride;
|
||||
data += aPoint.x * gfxASurface::BytePerPixelFromFormat(aFormat);
|
||||
return data;
|
||||
}
|
||||
|
||||
ShaderProgramType
|
||||
GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
GLContext::UploadImageDataToTexture(unsigned char* aData,
|
||||
int32_t aStride,
|
||||
gfxASurface::gfxImageFormat aFormat,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite,
|
||||
const nsIntPoint& aSrcPoint,
|
||||
bool aPixelBuffer,
|
||||
GLenum aTextureUnit)
|
||||
GLenum aTextureUnit,
|
||||
GLenum aTextureTarget)
|
||||
{
|
||||
bool textureInited = aOverwrite ? false : true;
|
||||
MakeCurrent();
|
||||
@ -2048,22 +2050,22 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
|
||||
if (!aTexture) {
|
||||
fGenTextures(1, &aTexture);
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
fBindTexture(aTextureTarget, aTexture);
|
||||
fTexParameteri(aTextureTarget,
|
||||
LOCAL_GL_TEXTURE_MIN_FILTER,
|
||||
LOCAL_GL_LINEAR);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
fTexParameteri(aTextureTarget,
|
||||
LOCAL_GL_TEXTURE_MAG_FILTER,
|
||||
LOCAL_GL_LINEAR);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
fTexParameteri(aTextureTarget,
|
||||
LOCAL_GL_TEXTURE_WRAP_S,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
fTexParameteri(aTextureTarget,
|
||||
LOCAL_GL_TEXTURE_WRAP_T,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
textureInited = false;
|
||||
} else {
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
|
||||
fBindTexture(aTextureTarget, aTexture);
|
||||
}
|
||||
|
||||
nsIntRegion paintRegion;
|
||||
@ -2073,46 +2075,11 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
paintRegion = aDstRegion;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
|
||||
unsigned char* data = NULL;
|
||||
|
||||
if (!imageSurface ||
|
||||
(imageSurface->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatRGB24 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatRGB16_565 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatA8)) {
|
||||
// We can't get suitable pixel data for the surface, make a copy
|
||||
nsIntRect bounds = aDstRegion.GetBounds();
|
||||
imageSurface =
|
||||
new gfxImageSurface(gfxIntSize(bounds.width, bounds.height),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
|
||||
|
||||
context->Translate(-gfxPoint(aSrcPoint.x, aSrcPoint.y));
|
||||
context->SetSource(aSurface);
|
||||
context->Paint();
|
||||
data = imageSurface->Data();
|
||||
NS_ASSERTION(!aPixelBuffer,
|
||||
"Must be using an image compatible surface with pixel buffers!");
|
||||
} else {
|
||||
// If a pixel buffer is bound the data pointer parameter is relative
|
||||
// to the start of the data block.
|
||||
if (!aPixelBuffer) {
|
||||
data = imageSurface->Data();
|
||||
}
|
||||
data += DataOffset(imageSurface, aSrcPoint);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(imageSurface);
|
||||
imageSurface->Flush();
|
||||
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
int32_t pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format());
|
||||
int32_t pixelSize = gfxASurface::BytePerPixelFromFormat(aFormat);
|
||||
ShaderProgramType shader;
|
||||
|
||||
switch (imageSurface->Format()) {
|
||||
switch (aFormat) {
|
||||
case gfxASurface::ImageFormatARGB32:
|
||||
format = LOCAL_GL_RGBA;
|
||||
type = LOCAL_GL_UNSIGNED_BYTE;
|
||||
@ -2143,7 +2110,11 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
shader = ShaderProgramType(0);
|
||||
}
|
||||
|
||||
int32_t stride = imageSurface->Stride();
|
||||
if (aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) {
|
||||
MOZ_ASSERT(aFormat == gfxASurface::ImageFormatARGB32,
|
||||
"unexpected format for rect texture");
|
||||
shader = BGRARectLayerProgramType;
|
||||
}
|
||||
|
||||
nsIntRegionRectIterator iter(paintRegion);
|
||||
const nsIntRect *iterRect;
|
||||
@ -2156,30 +2127,30 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
// bounding rectangle. We need to find the offset of this rect
|
||||
// within the region and adjust the data pointer accordingly.
|
||||
unsigned char *rectData =
|
||||
data + DataOffset(imageSurface, iterRect->TopLeft() - topLeft);
|
||||
aData + DataOffset(iterRect->TopLeft() - topLeft, aStride, aFormat);
|
||||
|
||||
NS_ASSERTION(textureInited || (iterRect->x == 0 && iterRect->y == 0),
|
||||
"Must be uploading to the origin when we don't have an existing texture");
|
||||
|
||||
if (textureInited && CanUploadSubTextures()) {
|
||||
TexSubImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
TexSubImage2D(aTextureTarget,
|
||||
0,
|
||||
iterRect->x,
|
||||
iterRect->y,
|
||||
iterRect->width,
|
||||
iterRect->height,
|
||||
stride,
|
||||
aStride,
|
||||
pixelSize,
|
||||
format,
|
||||
type,
|
||||
rectData);
|
||||
} else {
|
||||
TexImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
TexImage2D(aTextureTarget,
|
||||
0,
|
||||
format,
|
||||
iterRect->width,
|
||||
iterRect->height,
|
||||
stride,
|
||||
aStride,
|
||||
pixelSize,
|
||||
0,
|
||||
format,
|
||||
@ -2192,6 +2163,97 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
return shader;
|
||||
}
|
||||
|
||||
ShaderProgramType
|
||||
GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite,
|
||||
const nsIntPoint& aSrcPoint,
|
||||
bool aPixelBuffer,
|
||||
GLenum aTextureUnit,
|
||||
GLenum aTextureTarget)
|
||||
{
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
|
||||
unsigned char* data = NULL;
|
||||
|
||||
if (!imageSurface ||
|
||||
(imageSurface->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatRGB24 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatRGB16_565 &&
|
||||
imageSurface->Format() != gfxASurface::ImageFormatA8)) {
|
||||
// We can't get suitable pixel data for the surface, make a copy
|
||||
nsIntRect bounds = aDstRegion.GetBounds();
|
||||
imageSurface =
|
||||
new gfxImageSurface(gfxIntSize(bounds.width, bounds.height),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
|
||||
|
||||
context->Translate(-gfxPoint(aSrcPoint.x, aSrcPoint.y));
|
||||
context->SetSource(aSurface);
|
||||
context->Paint();
|
||||
data = imageSurface->Data();
|
||||
NS_ASSERTION(!aPixelBuffer,
|
||||
"Must be using an image compatible surface with pixel buffers!");
|
||||
} else {
|
||||
// If a pixel buffer is bound the data pointer parameter is relative
|
||||
// to the start of the data block.
|
||||
if (!aPixelBuffer) {
|
||||
data = imageSurface->Data();
|
||||
}
|
||||
data += DataOffset(aSrcPoint, imageSurface->Stride(),
|
||||
imageSurface->Format());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(imageSurface);
|
||||
imageSurface->Flush();
|
||||
|
||||
return UploadImageDataToTexture(data,
|
||||
imageSurface->Stride(),
|
||||
imageSurface->Format(),
|
||||
aDstRegion, aTexture, aOverwrite,
|
||||
aPixelBuffer, aTextureUnit, aTextureTarget);
|
||||
}
|
||||
|
||||
static gfxASurface::gfxImageFormat
|
||||
ImageFormatForSurfaceFormat(gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
case gfx::FORMAT_B8G8R8A8:
|
||||
return gfxASurface::ImageFormatARGB32;
|
||||
case gfx::FORMAT_B8G8R8X8:
|
||||
return gfxASurface::ImageFormatRGB24;
|
||||
case gfx::FORMAT_R5G6B5:
|
||||
return gfxASurface::ImageFormatRGB16_565;
|
||||
case gfx::FORMAT_A8:
|
||||
return gfxASurface::ImageFormatA8;
|
||||
default:
|
||||
return gfxASurface::ImageFormatUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderProgramType
|
||||
GLContext::UploadSurfaceToTexture(gfx::DataSourceSurface *aSurface,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite,
|
||||
const nsIntPoint& aSrcPoint,
|
||||
bool aPixelBuffer,
|
||||
GLenum aTextureUnit,
|
||||
GLenum aTextureTarget)
|
||||
{
|
||||
unsigned char* data = aPixelBuffer ? NULL : aSurface->GetData();
|
||||
int32_t stride = aSurface->Stride();
|
||||
gfxASurface::gfxImageFormat format =
|
||||
ImageFormatForSurfaceFormat(aSurface->GetFormat());
|
||||
data += DataOffset(aSrcPoint, stride, format);
|
||||
return UploadImageDataToTexture(data, stride, format,
|
||||
aDstRegion, aTexture, aOverwrite,
|
||||
aPixelBuffer, aTextureUnit,
|
||||
aTextureTarget);
|
||||
}
|
||||
|
||||
static GLint GetAddressAlignment(ptrdiff_t aAddress)
|
||||
{
|
||||
if (!(aAddress & 0x7)) {
|
||||
|
@ -61,6 +61,7 @@ namespace android {
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SharedSurface;
|
||||
class DataSourceSurface;
|
||||
struct SurfaceCaps;
|
||||
}
|
||||
|
||||
@ -864,7 +865,7 @@ public:
|
||||
* The aDstPoint parameter is ignored if no texture was provided
|
||||
* or aOverwrite is true.
|
||||
*
|
||||
* \param aSurface Surface to upload.
|
||||
* \param aData Image data to upload.
|
||||
* \param aDstRegion Region of texture to upload to.
|
||||
* \param aTexture Texture to use, or 0 to have one created for you.
|
||||
* \param aOverwrite Over an existing texture with a new one.
|
||||
@ -879,14 +880,39 @@ public:
|
||||
* texture unit being active.
|
||||
* \return Shader program needed to render this texture.
|
||||
*/
|
||||
ShaderProgramType UploadImageDataToTexture(unsigned char* aData,
|
||||
int32_t aStride,
|
||||
gfxASurface::gfxImageFormat aFormat,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite = false,
|
||||
bool aPixelBuffer = false,
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
|
||||
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
|
||||
|
||||
/**
|
||||
* Convenience wrapper around UploadImageDataToTexture for gfxASurfaces.
|
||||
*/
|
||||
ShaderProgramType UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite = false,
|
||||
const nsIntPoint& aSrcPoint = nsIntPoint(0, 0),
|
||||
bool aPixelBuffer = false,
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0);
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
|
||||
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
|
||||
|
||||
/**
|
||||
* Same as above, for DataSourceSurfaces.
|
||||
*/
|
||||
ShaderProgramType UploadSurfaceToTexture(gfx::DataSourceSurface *aSurface,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite = false,
|
||||
const nsIntPoint& aSrcPoint = nsIntPoint(0, 0),
|
||||
bool aPixelBuffer = false,
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
|
||||
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
|
||||
|
||||
void TexImage2D(GLenum target, GLint level, GLint internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei stride,
|
||||
|
@ -22,6 +22,7 @@ enum ShaderProgramType {
|
||||
RGBXLayerProgramType,
|
||||
BGRXLayerProgramType,
|
||||
RGBARectLayerProgramType,
|
||||
BGRARectLayerProgramType,
|
||||
RGBAExternalLayerProgramType,
|
||||
ColorLayerProgramType,
|
||||
YCbCrLayerProgramType,
|
||||
|
@ -95,6 +95,7 @@ BasicCompositor::BasicCompositor(nsIWidget *aWidget)
|
||||
|
||||
BasicCompositor::~BasicCompositor()
|
||||
{
|
||||
mWidget->CleanupRemoteDrawing();
|
||||
Destroy();
|
||||
MOZ_COUNT_DTOR(BasicCompositor);
|
||||
}
|
||||
@ -265,6 +266,8 @@ BasicCompositor::BeginFrame(const gfx::Rect *aClipRectIn,
|
||||
// If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Create a dummy
|
||||
// placeholder so that CreateRenderTarget() works.
|
||||
mDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1,1), FORMAT_B8G8R8A8);
|
||||
} else {
|
||||
mDrawTarget = mWidget->StartRemoteDrawing();
|
||||
}
|
||||
if (!mDrawTarget) {
|
||||
if (aRenderBoundsOut) {
|
||||
@ -303,6 +306,17 @@ BasicCompositor::EndFrame()
|
||||
mCopyTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
mCopyTarget->SetSource(thebes);
|
||||
mCopyTarget->Paint();
|
||||
} else {
|
||||
// Most platforms require us to buffer drawing to the widget surface.
|
||||
// That's why we don't draw to mDrawTarget directly.
|
||||
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
|
||||
mDrawTarget->DrawSurface(source,
|
||||
Rect(0, 0, mWidgetSize.width, mWidgetSize.height),
|
||||
Rect(0, 0, mWidgetSize.width, mWidgetSize.height),
|
||||
DrawSurfaceOptions(),
|
||||
DrawOptions());
|
||||
mDrawTarget = nullptr;
|
||||
mWidget->EndRemoteDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
virtual void FlushRendering() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return Compositor::GetBackend() == LAYERS_BASIC; }
|
||||
virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; }
|
||||
|
||||
ShadowableLayer* Hold(Layer* aLayer);
|
||||
|
||||
|
@ -126,6 +126,14 @@ ProgramProfileOGL::GetProfileFor(gl::ShaderProgramType aType,
|
||||
AddCommonTextureArgs(result);
|
||||
result.mTextureCount = 1;
|
||||
break;
|
||||
case gl::BGRARectLayerProgramType:
|
||||
MOZ_ASSERT(aMask == MaskNone, "BGRARectLayerProgramType can't handle masks.");
|
||||
result.mVertexShaderString = sLayerVS;
|
||||
result.mFragmentShaderString = sBGRARectTextureLayerFS;
|
||||
AddCommonArgs(result);
|
||||
AddCommonTextureArgs(result);
|
||||
result.mTextureCount = 1;
|
||||
break;
|
||||
case gl::RGBAExternalLayerProgramType:
|
||||
if (aMask == Mask3d) {
|
||||
result.mVertexShaderString = sLayerMask3DVS;
|
||||
|
@ -60,6 +60,10 @@ struct ProgramProfileOGL
|
||||
aType == gl::Copy2DRectProgramType))
|
||||
return false;
|
||||
|
||||
if (aMask != MaskNone &&
|
||||
aType == gl::BGRARectLayerProgramType)
|
||||
return false;
|
||||
|
||||
return aMask != Mask3d ||
|
||||
aType == gl::RGBARectLayerProgramType ||
|
||||
aType == gl::RGBALayerProgramType;
|
||||
|
@ -473,6 +473,34 @@ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
|
||||
#endif\n\
|
||||
";
|
||||
|
||||
static const char sBGRARectTextureLayerFS[] = "/* sBGRARectTextureLayerFS */\n\
|
||||
#extension GL_ARB_texture_rectangle : enable\n\
|
||||
/* Fragment Shader */\n\
|
||||
#ifdef GL_ES\n\
|
||||
#ifdef MEDIUMP_SHADER\n\
|
||||
precision mediump float;\n\
|
||||
#else\n\
|
||||
precision lowp float;\n\
|
||||
#endif\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#ifndef NO_LAYER_OPACITY\n\
|
||||
uniform float uLayerOpacity;\n\
|
||||
#endif\n\
|
||||
#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
|
||||
varying mediump vec2 vTexCoord;\n\
|
||||
#else\n\
|
||||
varying vec2 vTexCoord;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
uniform sampler2DRect uTexture;\n\
|
||||
uniform vec2 uTexCoordMultiplier;\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).bgra * uLayerOpacity;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
static const char sRGBAExternalTextureLayerFS[] = "/* sRGBAExternalTextureLayerFS */\n\
|
||||
#extension GL_OES_EGL_image_external : require\n\
|
||||
/* Fragment Shader */\n\
|
||||
|
@ -257,6 +257,22 @@ void main()
|
||||
#endif
|
||||
@end
|
||||
|
||||
// Single texture in BGRA format, but with a Rect texture.
|
||||
// nsChildView needs this for old Mac hardware.
|
||||
@shader sBGRARectTextureLayerFS
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
$LAYER_FRAGMENT<>$
|
||||
|
||||
uniform sampler2DRect uTexture;
|
||||
uniform vec2 uTexCoordMultiplier;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).bgra * uLayerOpacity;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
// Single texture in RGBA format, but uses external image. External
|
||||
// image is an EGLImage which have internal formats not otherwise
|
||||
// supported by OpenGL ES. It is up to the implementation exactly what
|
||||
|
@ -577,6 +577,12 @@ gfxUtils::ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion)
|
||||
ClipToRegionInternal(aContext, aRegion, false);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
gfxUtils::ClipToRegion(DrawTarget* aTarget, const nsIntRegion& aRegion)
|
||||
{
|
||||
ClipToRegionInternal(aTarget, aRegion, false);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
gfxUtils::ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion)
|
||||
{
|
||||
|
@ -66,13 +66,18 @@ public:
|
||||
*/
|
||||
static void ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion);
|
||||
|
||||
/**
|
||||
* Clip aTarget to the region aRegion.
|
||||
*/
|
||||
static void ClipToRegion(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
|
||||
|
||||
/**
|
||||
* Clip aContext to the region aRegion, snapping the rectangles.
|
||||
*/
|
||||
static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
|
||||
|
||||
/**
|
||||
* Clip aContext to the region aRegion, snapping the rectangles.
|
||||
* Clip aTarget to the region aRegion, snapping the rectangles.
|
||||
*/
|
||||
static void ClipToRegionSnapped(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
|
||||
|
||||
|
@ -84,11 +84,12 @@ class nsChildView;
|
||||
class nsCocoaWindow;
|
||||
union nsPluginPort;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class TextureImage;
|
||||
namespace {
|
||||
class GLPresenter;
|
||||
class RectTextureImage;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class GLManager;
|
||||
}
|
||||
@ -572,6 +573,10 @@ public:
|
||||
return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor());
|
||||
}
|
||||
|
||||
mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE;
|
||||
void EndRemoteDrawing() MOZ_OVERRIDE;
|
||||
void CleanupRemoteDrawing() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
void ReportMoveEvent();
|
||||
@ -590,7 +595,10 @@ protected:
|
||||
return widget.forget();
|
||||
}
|
||||
|
||||
void DoRemoteComposition(const nsIntRect& aRenderRect);
|
||||
|
||||
// Overlay drawing functions for OpenGL drawing
|
||||
void DrawWindowOverlay(mozilla::layers::GLManager* aManager, nsIntRect aRect);
|
||||
void MaybeDrawResizeIndicator(mozilla::layers::GLManager* aManager, const nsIntRect& aRect);
|
||||
void MaybeDrawRoundedCorners(mozilla::layers::GLManager* aManager, const nsIntRect& aRect);
|
||||
void MaybeDrawTitlebar(mozilla::layers::GLManager* aManager, const nsIntRect& aRect);
|
||||
@ -599,10 +607,6 @@ protected:
|
||||
// determined by mDirtyTitlebarRegion.
|
||||
void UpdateTitlebarImageBuffer();
|
||||
|
||||
// Upload the contents of mTitlebarImageBuffer to mTitlebarImage on the
|
||||
// compositor thread, as determined by mUpdatedTitlebarRegion.
|
||||
void UpdateTitlebarImage(mozilla::layers::GLManager* aManager, const nsIntRect& aRect);
|
||||
|
||||
nsIntRect RectContainingTitlebarControls();
|
||||
|
||||
nsIWidget* GetWidgetForListenerEvents();
|
||||
@ -640,14 +644,13 @@ protected:
|
||||
// transaction. Accessed from any thread, protected by mEffectsLock.
|
||||
nsIntRegion mUpdatedTitlebarRegion;
|
||||
|
||||
nsRefPtr<gfxQuartzSurface> mTitlebarImageBuffer;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTitlebarImageBuffer;
|
||||
|
||||
// Compositor thread only
|
||||
bool mFailedResizerImage;
|
||||
bool mFailedCornerMaskImage;
|
||||
nsRefPtr<mozilla::gl::TextureImage> mResizerImage;
|
||||
nsRefPtr<mozilla::gl::TextureImage> mCornerMaskImage;
|
||||
nsRefPtr<mozilla::gl::TextureImage> mTitlebarImage;
|
||||
nsAutoPtr<RectTextureImage> mResizerImage;
|
||||
nsAutoPtr<RectTextureImage> mCornerMaskImage;
|
||||
nsAutoPtr<RectTextureImage> mTitlebarImage;
|
||||
nsAutoPtr<RectTextureImage> mBasicCompositorImage;
|
||||
|
||||
// The area of mTitlebarImageBuffer that has changed and needs to be
|
||||
// uploaded to to mTitlebarImage. Main thread only.
|
||||
@ -667,6 +670,10 @@ protected:
|
||||
NP_CGContext mPluginCGContext;
|
||||
nsIPluginInstanceOwner* mPluginInstanceOwner; // [WEAK]
|
||||
|
||||
// Used in OMTC BasicLayers mode. Presents the BasicCompositor result
|
||||
// surface to the screen using an OpenGL context.
|
||||
nsAutoPtr<GLPresenter> mGLPresenter;
|
||||
|
||||
static uint32_t sLastInputEventCount;
|
||||
};
|
||||
|
||||
|
@ -55,9 +55,13 @@
|
||||
#include "ClientLayerManager.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "GLTextureImage.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "mozilla/layers/GLManager.h"
|
||||
#include "mozilla/layers/CompositorCocoaWidgetHelper.h"
|
||||
#include "mozilla/layers/CompositorOGL.h"
|
||||
#include "mozilla/layers/BasicCompositor.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "mozilla/a11y/Platform.h"
|
||||
@ -243,6 +247,103 @@ void EnsureLogInitialized()
|
||||
#endif // PR_LOGGING
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Manages a texture which can resize dynamically, binds to the
|
||||
// LOCAL_GL_TEXTURE_RECTANGLE_ARB texture target and is automatically backed
|
||||
// by a power-of-two size GL texture. The latter two features are used for
|
||||
// compatibility with older Mac hardware which we block GL layers on.
|
||||
// RectTextureImages are used both for accelerated GL layers drawing and for
|
||||
// OMTC BasicLayers drawing.
|
||||
class RectTextureImage {
|
||||
public:
|
||||
RectTextureImage(GLContext* aGLContext)
|
||||
: mGLContext(aGLContext)
|
||||
, mTexture(0)
|
||||
, mInUpdate(false)
|
||||
{}
|
||||
|
||||
virtual ~RectTextureImage();
|
||||
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
BeginUpdate(const nsIntSize& aNewSize,
|
||||
const nsIntRegion& aDirtyRegion = nsIntRegion());
|
||||
void EndUpdate(bool aKeepSurface = false);
|
||||
|
||||
void UpdateIfNeeded(const nsIntSize& aNewSize,
|
||||
const nsIntRegion& aDirtyRegion,
|
||||
void (^aCallback)(gfx::DrawTarget*, const nsIntRegion&))
|
||||
{
|
||||
RefPtr<gfx::DrawTarget> drawTarget = BeginUpdate(aNewSize, aDirtyRegion);
|
||||
if (drawTarget) {
|
||||
aCallback(drawTarget, GetUpdateRegion());
|
||||
EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
nsIntRegion GetUpdateRegion() {
|
||||
MOZ_ASSERT(mInUpdate, "update region only valid during update");
|
||||
return mUpdateRegion;
|
||||
}
|
||||
|
||||
void Draw(mozilla::layers::GLManager* aManager,
|
||||
const nsIntPoint& aLocation,
|
||||
const gfx3DMatrix& aTransform = gfx3DMatrix());
|
||||
|
||||
protected:
|
||||
nsIntSize TextureSizeForSize(const nsIntSize& aSize);
|
||||
|
||||
RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
|
||||
GLContext* mGLContext;
|
||||
nsIntRegion mUpdateRegion;
|
||||
nsIntSize mUsedSize;
|
||||
nsIntSize mBufferSize;
|
||||
nsIntSize mTextureSize;
|
||||
GLuint mTexture;
|
||||
bool mInUpdate;
|
||||
};
|
||||
|
||||
// Used for OpenGL drawing from the compositor thread for OMTC BasicLayers.
|
||||
// We need to use OpenGL for this because there seems to be no other robust
|
||||
// way of drawing from a secondary thread without locking, which would cause
|
||||
// deadlocks in our setup. See bug 882523.
|
||||
class GLPresenter : public GLManager
|
||||
{
|
||||
public:
|
||||
static GLPresenter* CreateForWindow(nsIWidget* aWindow)
|
||||
{
|
||||
nsRefPtr<GLContext> context = gl::GLContextProvider::CreateForWindow(aWindow);
|
||||
return context ? new GLPresenter(context) : nullptr;
|
||||
}
|
||||
|
||||
GLPresenter(GLContext* aContext);
|
||||
virtual ~GLPresenter();
|
||||
|
||||
virtual GLContext* gl() const MOZ_OVERRIDE { return mGLContext; }
|
||||
virtual ShaderProgramOGL* GetProgram(gl::ShaderProgramType aType) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(aType == BGRARectLayerProgramType, "unexpected program type");
|
||||
return mBGRARectProgram;
|
||||
}
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) MOZ_OVERRIDE;
|
||||
|
||||
void BeginFrame(nsIntSize aRenderSize);
|
||||
void EndFrame();
|
||||
|
||||
NSOpenGLContext* GetNSOpenGLContext()
|
||||
{
|
||||
return static_cast<NSOpenGLContext*>(
|
||||
mGLContext->GetNativeData(GLContext::NativeGLContext));
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
nsAutoPtr<mozilla::layers::ShaderProgramOGL> mBGRARectProgram;
|
||||
GLuint mQuadVBO;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsChildView::nsChildView() : nsBaseWidget()
|
||||
@ -253,8 +354,6 @@ nsChildView::nsChildView() : nsBaseWidget()
|
||||
, mShowsResizeIndicator(false)
|
||||
, mHasRoundedBottomCorners(false)
|
||||
, mIsCoveringTitlebar(false)
|
||||
, mFailedResizerImage(false)
|
||||
, mFailedCornerMaskImage(false)
|
||||
, mBackingScaleFactor(0.0)
|
||||
, mVisible(false)
|
||||
, mDrawing(false)
|
||||
@ -1387,8 +1486,7 @@ NS_IMETHODIMP nsChildView::Invalidate(const nsIntRect &aRect)
|
||||
if (!mView || !mVisible)
|
||||
return NS_OK;
|
||||
|
||||
NS_ASSERTION(GetLayerManager()->GetBackendType() != LAYERS_CLIENT ||
|
||||
Compositor::GetBackend() == LAYERS_BASIC,
|
||||
NS_ASSERTION(GetLayerManager()->GetBackendType() != LAYERS_CLIENT,
|
||||
"Shouldn't need to invalidate with accelerated OMTC layers!");
|
||||
|
||||
if ([NSView focusView]) {
|
||||
@ -1419,11 +1517,20 @@ nsChildView::ComputeShouldAccelerate(bool aDefault)
|
||||
bool
|
||||
nsChildView::ShouldUseOffMainThreadCompositing()
|
||||
{
|
||||
// OMTC doesn't work with Basic Layers on OS X right now. Once it works, we'll
|
||||
// still want to disable it for certain kinds of windows (e.g. popups).
|
||||
return nsBaseWidget::ShouldUseOffMainThreadCompositing() &&
|
||||
(ComputeShouldAccelerate(mUseLayersAcceleration) ||
|
||||
Preferences::GetBool("layers.offmainthreadcomposition.prefer-basic", false));
|
||||
// When acceleration is off, default to false, but allow force-enabling
|
||||
// using the layers.offmainthreadcomposition.prefer-basic pref.
|
||||
if (!ComputeShouldAccelerate(mUseLayersAcceleration) &&
|
||||
!Preferences::GetBool("layers.offmainthreadcomposition.prefer-basic", false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't use OMTC (which requires OpenGL) for transparent windows or for
|
||||
// popup windows.
|
||||
if (!mView || ![[mView window] isOpaque] ||
|
||||
[[mView window] isKindOfClass:[PopupWindow class]])
|
||||
return false;
|
||||
|
||||
return nsBaseWidget::ShouldUseOffMainThreadCompositing();
|
||||
}
|
||||
|
||||
inline uint16_t COLOR8TOCOLOR16(uint8_t color8)
|
||||
@ -1908,26 +2015,25 @@ void
|
||||
nsChildView::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
|
||||
{
|
||||
nsAutoPtr<GLManager> manager(GLManager::CreateGLManager(aManager));
|
||||
if (!manager) {
|
||||
return;
|
||||
if (manager) {
|
||||
DrawWindowOverlay(manager, aRect);
|
||||
}
|
||||
}
|
||||
|
||||
manager->gl()->PushScissorRect(aRect);
|
||||
|
||||
MaybeDrawTitlebar(manager, aRect);
|
||||
MaybeDrawResizeIndicator(manager, aRect);
|
||||
MaybeDrawRoundedCorners(manager, aRect);
|
||||
|
||||
manager->gl()->PopScissorRect();
|
||||
void
|
||||
nsChildView::DrawWindowOverlay(GLManager* aManager, nsIntRect aRect)
|
||||
{
|
||||
MaybeDrawTitlebar(aManager, aRect);
|
||||
MaybeDrawResizeIndicator(aManager, aRect);
|
||||
MaybeDrawRoundedCorners(aManager, aRect);
|
||||
}
|
||||
|
||||
static void
|
||||
ClearRegion(gfxASurface* aSurface, nsIntRegion aRegion)
|
||||
ClearRegion(gfx::DrawTarget *aDT, nsIntRegion aRegion)
|
||||
{
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
|
||||
gfxUtils::ClipToRegion(ctx, aRegion);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
ctx->Paint();
|
||||
gfxUtils::ClipToRegion(aDT, aRegion);
|
||||
aDT->ClearRect(gfx::Rect(0, 0, aDT->GetSize().width, aDT->GetSize().height));
|
||||
aDT->PopClip();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1967,66 +2073,21 @@ void
|
||||
nsChildView::MaybeDrawResizeIndicator(GLManager* aManager, const nsIntRect& aRect)
|
||||
{
|
||||
MutexAutoLock lock(mEffectsLock);
|
||||
if (!mShowsResizeIndicator || mFailedResizerImage) {
|
||||
if (!mShowsResizeIndicator) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mResizerImage) {
|
||||
mResizerImage =
|
||||
aManager->gl()->CreateTextureImage(nsIntSize(mResizeIndicatorRect.width,
|
||||
mResizeIndicatorRect.height),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
TextureImage::UseNearestFilter);
|
||||
|
||||
// Creation of texture images can fail.
|
||||
if (!mResizerImage)
|
||||
return;
|
||||
|
||||
nsIntRegion update(nsIntRect(0, 0, mResizeIndicatorRect.width, mResizeIndicatorRect.height));
|
||||
gfxASurface *asurf = mResizerImage->BeginUpdate(update);
|
||||
if (!asurf) {
|
||||
mResizerImage = nullptr;
|
||||
return;
|
||||
mResizerImage = new RectTextureImage(aManager->gl());
|
||||
}
|
||||
|
||||
// We need a Quartz surface because DrawResizer wants a CGContext.
|
||||
if (asurf->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
NS_WARN_IF_FALSE(FALSE, "mResizerImage's surface is not Quartz");
|
||||
mResizerImage->EndUpdate();
|
||||
mResizerImage = nullptr;
|
||||
mFailedResizerImage = true;
|
||||
return;
|
||||
}
|
||||
nsIntSize size = mResizeIndicatorRect.Size();
|
||||
mResizerImage->UpdateIfNeeded(size, nsIntRegion(), ^(gfx::DrawTarget* drawTarget, const nsIntRegion& updateRegion) {
|
||||
ClearRegion(drawTarget, updateRegion);
|
||||
DrawResizer(static_cast<CGContextRef>(drawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT)));
|
||||
});
|
||||
|
||||
ClearRegion(asurf, update);
|
||||
|
||||
nsRefPtr<gfxQuartzSurface> image = static_cast<gfxQuartzSurface*>(asurf);
|
||||
DrawResizer(image->GetCGContext());
|
||||
|
||||
mResizerImage->EndUpdate();
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(mResizerImage, "Must have a texture allocated by now!");
|
||||
|
||||
float bottomX = aRect.XMost();
|
||||
float bottomY = aRect.YMost();
|
||||
|
||||
TextureImage::ScopedBindTexture texBind(mResizerImage, LOCAL_GL_TEXTURE0);
|
||||
|
||||
ShaderProgramOGL *program =
|
||||
aManager->GetProgram(mResizerImage->GetShaderProgramType());
|
||||
program->Activate();
|
||||
program->SetLayerQuadRect(nsIntRect(bottomX - resizeIndicatorWidth,
|
||||
bottomY - resizeIndicatorHeight,
|
||||
resizeIndicatorWidth,
|
||||
resizeIndicatorHeight));
|
||||
program->SetLayerTransform(gfx3DMatrix());
|
||||
program->SetLayerOpacity(1.0);
|
||||
program->SetRenderOffset(nsIntPoint(0,0));
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
aManager->BindAndDrawQuad(program);
|
||||
mResizerImage->Draw(aManager, mResizeIndicatorRect.TopLeft());
|
||||
}
|
||||
|
||||
// Draw the highlight line at the top of the titlebar.
|
||||
@ -2066,12 +2127,14 @@ nsChildView::UpdateTitlebarImageBuffer()
|
||||
nsIntRegion dirtyTitlebarRegion = mDirtyTitlebarRegion;
|
||||
mDirtyTitlebarRegion.SetEmpty();
|
||||
|
||||
gfx::IntSize titlebarSize(mTitlebarRect.width, mTitlebarRect.height);
|
||||
if (!mTitlebarImageBuffer ||
|
||||
mTitlebarImageBuffer->GetSize() != mTitlebarRect.Size()) {
|
||||
mTitlebarImageBuffer->GetSize() != titlebarSize) {
|
||||
dirtyTitlebarRegion = mTitlebarRect;
|
||||
|
||||
mTitlebarImageBuffer = new gfxQuartzSurface(mTitlebarRect.Size(),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
mTitlebarImageBuffer =
|
||||
gfx::Factory::CreateDrawTarget(gfx::BACKEND_COREGRAPHICS, titlebarSize,
|
||||
gfx::FORMAT_B8G8R8A8);
|
||||
}
|
||||
|
||||
if (dirtyTitlebarRegion.IsEmpty())
|
||||
@ -2079,7 +2142,8 @@ nsChildView::UpdateTitlebarImageBuffer()
|
||||
|
||||
ClearRegion(mTitlebarImageBuffer, dirtyTitlebarRegion);
|
||||
|
||||
CGContextRef ctx = mTitlebarImageBuffer->GetCGContext();
|
||||
CGContextRef ctx =
|
||||
static_cast<CGContextRef>(mTitlebarImageBuffer->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT));
|
||||
CGContextSaveGState(ctx);
|
||||
|
||||
double scale = BackingScaleFactor();
|
||||
@ -2151,45 +2215,6 @@ nsChildView::UpdateTitlebarImageBuffer()
|
||||
mUpdatedTitlebarRegion.Or(mUpdatedTitlebarRegion, dirtyTitlebarRegion);
|
||||
}
|
||||
|
||||
// When this method is entered, mEffectsLock is already being held.
|
||||
void
|
||||
nsChildView::UpdateTitlebarImage(GLManager* aManager, const nsIntRect& aRect)
|
||||
{
|
||||
nsIntRegion updatedTitlebarRegion;
|
||||
updatedTitlebarRegion.And(mUpdatedTitlebarRegion, mTitlebarRect);
|
||||
mUpdatedTitlebarRegion.SetEmpty();
|
||||
|
||||
if (!mTitlebarImage || mTitlebarImage->GetSize() != mTitlebarRect.Size()) {
|
||||
updatedTitlebarRegion = mTitlebarRect;
|
||||
|
||||
mTitlebarImage =
|
||||
aManager->gl()->CreateTextureImage(mTitlebarRect.Size(),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
TextureImage::UseNearestFilter);
|
||||
|
||||
// Creation of texture images can fail.
|
||||
if (!mTitlebarImage)
|
||||
return;
|
||||
}
|
||||
|
||||
if (updatedTitlebarRegion.IsEmpty())
|
||||
return;
|
||||
|
||||
gfxASurface *asurf = mTitlebarImage->BeginUpdate(updatedTitlebarRegion);
|
||||
if (!asurf) {
|
||||
mTitlebarImage = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(asurf);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(mTitlebarImageBuffer);
|
||||
ctx->Paint();
|
||||
|
||||
mTitlebarImage->EndUpdate();
|
||||
}
|
||||
|
||||
// This method draws an overlay in the top of the window which contains the
|
||||
// titlebar controls (e.g. close, min, zoom, fullscreen) and the titlebar
|
||||
// highlight effect.
|
||||
@ -2208,25 +2233,26 @@ nsChildView::MaybeDrawTitlebar(GLManager* aManager, const nsIntRect& aRect)
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTitlebarImage(aManager, aRect);
|
||||
nsIntRegion updatedTitlebarRegion;
|
||||
updatedTitlebarRegion.And(mUpdatedTitlebarRegion, mTitlebarRect);
|
||||
mUpdatedTitlebarRegion.SetEmpty();
|
||||
|
||||
if (!mTitlebarImage) {
|
||||
return;
|
||||
mTitlebarImage = new RectTextureImage(aManager->gl());
|
||||
}
|
||||
|
||||
TextureImage::ScopedBindTexture texBind(mTitlebarImage, LOCAL_GL_TEXTURE0);
|
||||
mTitlebarImage->UpdateIfNeeded(mTitlebarRect.Size(), updatedTitlebarRegion,
|
||||
^(gfx::DrawTarget* drawTarget, const nsIntRegion& updateRegion) {
|
||||
RefPtr<gfx::SourceSurface> source = mTitlebarImageBuffer->Snapshot();
|
||||
gfx::Rect rect(0, 0, mTitlebarRect.width, mTitlebarRect.height);
|
||||
gfxUtils::ClipToRegion(drawTarget, updateRegion);
|
||||
drawTarget->DrawSurface(source, rect, rect,
|
||||
gfx::DrawSurfaceOptions(),
|
||||
gfx::DrawOptions(1.0, gfx::OP_SOURCE));
|
||||
drawTarget->PopClip();
|
||||
});
|
||||
|
||||
ShaderProgramOGL *program =
|
||||
aManager->GetProgram(mTitlebarImage->GetShaderProgramType());
|
||||
program->Activate();
|
||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0),
|
||||
mTitlebarImage->GetSize()));
|
||||
program->SetLayerTransform(gfx3DMatrix());
|
||||
program->SetLayerOpacity(1.0);
|
||||
program->SetRenderOffset(nsIntPoint(0,0));
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
aManager->BindAndDrawQuad(program);
|
||||
mTitlebarImage->Draw(aManager, mTitlebarRect.TopLeft());
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2241,80 +2267,34 @@ nsChildView::MaybeDrawRoundedCorners(GLManager* aManager, const nsIntRect& aRect
|
||||
{
|
||||
MutexAutoLock lock(mEffectsLock);
|
||||
|
||||
if (mFailedCornerMaskImage) {
|
||||
return;
|
||||
if (!mCornerMaskImage) {
|
||||
mCornerMaskImage = new RectTextureImage(aManager->gl());
|
||||
}
|
||||
|
||||
if (!mCornerMaskImage ||
|
||||
mCornerMaskImage->GetSize().width != mDevPixelCornerRadius) {
|
||||
mCornerMaskImage =
|
||||
aManager->gl()->CreateTextureImage(nsIntSize(mDevPixelCornerRadius,
|
||||
mDevPixelCornerRadius),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
TextureImage::UseNearestFilter);
|
||||
|
||||
// Creation of texture images can fail.
|
||||
if (!mCornerMaskImage)
|
||||
return;
|
||||
|
||||
nsIntRegion update(nsIntRect(0, 0, mDevPixelCornerRadius, mDevPixelCornerRadius));
|
||||
gfxASurface *asurf = mCornerMaskImage->BeginUpdate(update);
|
||||
if (!asurf) {
|
||||
mCornerMaskImage = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (asurf->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
NS_WARNING("mCornerMaskImage's surface is not Quartz");
|
||||
mCornerMaskImage->EndUpdate();
|
||||
mCornerMaskImage = nullptr;
|
||||
mFailedCornerMaskImage = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ClearRegion(asurf, update);
|
||||
|
||||
nsRefPtr<gfxQuartzSurface> image = static_cast<gfxQuartzSurface*>(asurf);
|
||||
DrawTopLeftCornerMask(image->GetCGContext(), mDevPixelCornerRadius);
|
||||
|
||||
mCornerMaskImage->EndUpdate();
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(mCornerMaskImage, "Must have a texture allocated by now!");
|
||||
|
||||
TextureImage::ScopedBindTexture texBind(mCornerMaskImage, LOCAL_GL_TEXTURE0);
|
||||
|
||||
ShaderProgramOGL *program = aManager->GetProgram(mCornerMaskImage->GetShaderProgramType());
|
||||
program->Activate();
|
||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0),
|
||||
mCornerMaskImage->GetSize()));
|
||||
program->SetLayerOpacity(1.0);
|
||||
program->SetRenderOffset(nsIntPoint(0,0));
|
||||
program->SetTextureUnit(0);
|
||||
nsIntSize size(mDevPixelCornerRadius, mDevPixelCornerRadius);
|
||||
mCornerMaskImage->UpdateIfNeeded(size, nsIntRegion(), ^(gfx::DrawTarget* drawTarget, const nsIntRegion& updateRegion) {
|
||||
ClearRegion(drawTarget, updateRegion);
|
||||
DrawTopLeftCornerMask(static_cast<CGContextRef>(drawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT)),
|
||||
mDevPixelCornerRadius);
|
||||
});
|
||||
|
||||
// Use operator destination in: multiply all 4 channels with source alpha.
|
||||
aManager->gl()->fBlendFuncSeparate(LOCAL_GL_ZERO, LOCAL_GL_SRC_ALPHA,
|
||||
LOCAL_GL_ZERO, LOCAL_GL_SRC_ALPHA);
|
||||
|
||||
gfx3DMatrix flipX = gfx3DMatrix::ScalingMatrix(-1, 1, 1);
|
||||
gfx3DMatrix flipY = gfx3DMatrix::ScalingMatrix(1, -1, 1);
|
||||
|
||||
if (mIsCoveringTitlebar) {
|
||||
// Mask the top corners.
|
||||
program->SetLayerTransform(gfx3DMatrix::ScalingMatrix(1, 1, 1) *
|
||||
gfx3DMatrix::Translation(0, 0, 0));
|
||||
aManager->BindAndDrawQuad(program);
|
||||
program->SetLayerTransform(gfx3DMatrix::ScalingMatrix(-1, 1, 1) *
|
||||
gfx3DMatrix::Translation(aRect.width, 0, 0));
|
||||
aManager->BindAndDrawQuad(program);
|
||||
mCornerMaskImage->Draw(aManager, aRect.TopLeft());
|
||||
mCornerMaskImage->Draw(aManager, aRect.TopRight(), flipX);
|
||||
}
|
||||
|
||||
if (mHasRoundedBottomCorners) {
|
||||
// Mask the bottom corners.
|
||||
program->SetLayerTransform(gfx3DMatrix::ScalingMatrix(1, -1, 1) *
|
||||
gfx3DMatrix::Translation(0, aRect.height, 0));
|
||||
aManager->BindAndDrawQuad(program);
|
||||
program->SetLayerTransform(gfx3DMatrix::ScalingMatrix(-1, -1, 1) *
|
||||
gfx3DMatrix::Translation(aRect.width, aRect.height, 0));
|
||||
aManager->BindAndDrawQuad(program);
|
||||
mCornerMaskImage->Draw(aManager, aRect.BottomLeft(), flipY);
|
||||
mCornerMaskImage->Draw(aManager, aRect.BottomRight(), flipY * flipX);
|
||||
}
|
||||
|
||||
// Reset blend mode.
|
||||
@ -2376,6 +2356,69 @@ nsChildView::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometri
|
||||
[win setUnifiedToolbarHeight:DevPixelsToCocoaPoints(devUnifiedHeight)];
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
nsChildView::StartRemoteDrawing()
|
||||
{
|
||||
if (!mGLPresenter) {
|
||||
mGLPresenter = GLPresenter::CreateForWindow(this);
|
||||
|
||||
if (!mGLPresenter) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsIntRegion dirtyRegion = mBounds;
|
||||
nsIntSize renderSize = mBounds.Size();
|
||||
|
||||
if (!mBasicCompositorImage) {
|
||||
mBasicCompositorImage = new RectTextureImage(mGLPresenter->gl());
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTarget> drawTarget =
|
||||
mBasicCompositorImage->BeginUpdate(renderSize, dirtyRegion);
|
||||
|
||||
if (!drawTarget) {
|
||||
// Composite unchanged textures.
|
||||
DoRemoteComposition(mBounds);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return drawTarget;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::EndRemoteDrawing()
|
||||
{
|
||||
mBasicCompositorImage->EndUpdate(true);
|
||||
DoRemoteComposition(mBounds);
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::CleanupRemoteDrawing()
|
||||
{
|
||||
mBasicCompositorImage = nullptr;
|
||||
mCornerMaskImage = nullptr;
|
||||
mResizerImage = nullptr;
|
||||
mTitlebarImage = nullptr;
|
||||
mGLPresenter = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::DoRemoteComposition(const nsIntRect& aRenderRect)
|
||||
{
|
||||
[(ChildView*)mView preRender:mGLPresenter->GetNSOpenGLContext()];
|
||||
mGLPresenter->BeginFrame(aRenderRect.Size());
|
||||
|
||||
// Draw the result from the basic compositor.
|
||||
mBasicCompositorImage->Draw(mGLPresenter, nsIntPoint(0, 0));
|
||||
|
||||
// DrawWindowOverlay doesn't do anything for non-GL, so it didn't paint
|
||||
// anything during the basic compositor transaction. Draw the overlay now.
|
||||
DrawWindowOverlay(mGLPresenter, aRenderRect);
|
||||
|
||||
mGLPresenter->EndFrame();
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
already_AddRefed<a11y::Accessible>
|
||||
nsChildView::GetDocumentAccessible()
|
||||
@ -2399,6 +2442,211 @@ nsChildView::GetDocumentAccessible()
|
||||
}
|
||||
#endif
|
||||
|
||||
// RectTextureImage implementation
|
||||
|
||||
RectTextureImage::~RectTextureImage()
|
||||
{
|
||||
if (mTexture) {
|
||||
mGLContext->MakeCurrent();
|
||||
mGLContext->fDeleteTextures(1, &mTexture);
|
||||
mTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
RectTextureImage::TextureSizeForSize(const nsIntSize& aSize)
|
||||
{
|
||||
return nsIntSize(gfx::NextPowerOfTwo(aSize.width),
|
||||
gfx::NextPowerOfTwo(aSize.height));
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
RectTextureImage::BeginUpdate(const nsIntSize& aNewSize,
|
||||
const nsIntRegion& aDirtyRegion)
|
||||
{
|
||||
MOZ_ASSERT(!mInUpdate, "Beginning update during update!");
|
||||
mUpdateRegion = aDirtyRegion;
|
||||
if (aNewSize != mUsedSize) {
|
||||
mUsedSize = aNewSize;
|
||||
mUpdateRegion = nsIntRect(nsIntPoint(0, 0), aNewSize);
|
||||
}
|
||||
|
||||
if (mUpdateRegion.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIntSize neededBufferSize = TextureSizeForSize(mUsedSize);
|
||||
if (!mUpdateDrawTarget || mBufferSize != neededBufferSize) {
|
||||
gfx::IntSize size(neededBufferSize.width, neededBufferSize.height);
|
||||
mUpdateDrawTarget =
|
||||
gfx::Factory::CreateDrawTarget(gfx::BACKEND_COREGRAPHICS, size,
|
||||
gfx::FORMAT_B8G8R8A8);
|
||||
mBufferSize = neededBufferSize;
|
||||
}
|
||||
|
||||
mInUpdate = true;
|
||||
|
||||
RefPtr<gfx::DrawTarget> drawTarget = mUpdateDrawTarget;
|
||||
return drawTarget;
|
||||
}
|
||||
|
||||
#define NSFoundationVersionWithProperStrideSupportForSubtextureUpload NSFoundationVersionNumber10_6_3
|
||||
|
||||
static bool
|
||||
CanUploadSubtextures()
|
||||
{
|
||||
return NSFoundationVersionNumber >= NSFoundationVersionWithProperStrideSupportForSubtextureUpload;
|
||||
}
|
||||
|
||||
void
|
||||
RectTextureImage::EndUpdate(bool aKeepSurface)
|
||||
{
|
||||
MOZ_ASSERT(mInUpdate, "Ending update while not in update");
|
||||
|
||||
bool overwriteTexture = false;
|
||||
nsIntRegion updateRegion = mUpdateRegion;
|
||||
if (!mTexture || (mTextureSize != mBufferSize)) {
|
||||
overwriteTexture = true;
|
||||
mTextureSize = mBufferSize;
|
||||
}
|
||||
|
||||
if (overwriteTexture || !CanUploadSubtextures()) {
|
||||
updateRegion = nsIntRect(nsIntPoint(0, 0), mTextureSize);
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> snapshot = mUpdateDrawTarget->Snapshot();
|
||||
RefPtr<gfx::DataSourceSurface> dataSnapshot = snapshot->GetDataSurface();
|
||||
|
||||
mGLContext->UploadSurfaceToTexture(dataSnapshot,
|
||||
updateRegion,
|
||||
mTexture,
|
||||
overwriteTexture,
|
||||
updateRegion.GetBounds().TopLeft(),
|
||||
false,
|
||||
LOCAL_GL_TEXTURE0,
|
||||
LOCAL_GL_TEXTURE_RECTANGLE_ARB);
|
||||
|
||||
if (!aKeepSurface) {
|
||||
mUpdateDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
mInUpdate = false;
|
||||
}
|
||||
|
||||
void
|
||||
RectTextureImage::Draw(GLManager* aManager,
|
||||
const nsIntPoint& aLocation,
|
||||
const gfx3DMatrix& aTransform)
|
||||
{
|
||||
ShaderProgramOGL* program = aManager->GetProgram(gl::BGRARectLayerProgramType);
|
||||
|
||||
aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTexture);
|
||||
|
||||
program->Activate();
|
||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mUsedSize));
|
||||
program->SetLayerTransform(aTransform * gfx3DMatrix::Translation(aLocation.x, aLocation.y, 0));
|
||||
program->SetLayerOpacity(1.0);
|
||||
program->SetRenderOffset(nsIntPoint(0, 0));
|
||||
program->SetTexCoordMultiplier(mUsedSize.width, mUsedSize.height);
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
aManager->BindAndDrawQuad(program);
|
||||
|
||||
aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
}
|
||||
|
||||
// GLPresenter implementation
|
||||
|
||||
GLPresenter::GLPresenter(GLContext* aContext)
|
||||
: mGLContext(aContext)
|
||||
{
|
||||
mGLContext->SetFlipped(true);
|
||||
mGLContext->MakeCurrent();
|
||||
mBGRARectProgram = new ShaderProgramOGL(mGLContext,
|
||||
ProgramProfileOGL::GetProfileFor(gl::BGRARectLayerProgramType, MaskNone));
|
||||
|
||||
// Create mQuadVBO.
|
||||
mGLContext->fGenBuffers(1, &mQuadVBO);
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
|
||||
|
||||
GLfloat vertices[] = {
|
||||
/* First quad vertices */
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
/* Then quad texcoords */
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(vertices), vertices, LOCAL_GL_STATIC_DRAW);
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
GLPresenter::~GLPresenter()
|
||||
{
|
||||
if (mQuadVBO) {
|
||||
mGLContext->MakeCurrent();
|
||||
mGLContext->fDeleteBuffers(1, &mQuadVBO);
|
||||
mQuadVBO = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GLPresenter::BindAndDrawQuad(ShaderProgramOGL* aProgram)
|
||||
{
|
||||
mGLContext->MakeCurrent();
|
||||
|
||||
GLuint vertAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||
GLuint texCoordAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
|
||||
mGLContext->fVertexAttribPointer(vertAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*)0);
|
||||
mGLContext->fEnableVertexAttribArray(vertAttribIndex);
|
||||
mGLContext->fVertexAttribPointer(texCoordAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*) (sizeof(float)*4*2));
|
||||
mGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
|
||||
mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
mGLContext->fDisableVertexAttribArray(vertAttribIndex);
|
||||
mGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
|
||||
}
|
||||
|
||||
void
|
||||
GLPresenter::BeginFrame(nsIntSize aRenderSize)
|
||||
{
|
||||
mGLContext->MakeCurrent();
|
||||
|
||||
mGLContext->fViewport(0, 0, aRenderSize.width, aRenderSize.height);
|
||||
|
||||
// Matrix to transform (0, 0, width, height) to viewport space (-1.0, 1.0,
|
||||
// 2, 2) and flip the contents.
|
||||
gfxMatrix viewMatrix;
|
||||
viewMatrix.Translate(-gfxPoint(1.0, -1.0));
|
||||
viewMatrix.Scale(2.0f / float(aRenderSize.width), 2.0f / float(aRenderSize.height));
|
||||
viewMatrix.Scale(1.0f, -1.0f);
|
||||
|
||||
gfx3DMatrix matrix3d = gfx3DMatrix::From2D(viewMatrix);
|
||||
matrix3d._33 = 0.0f;
|
||||
|
||||
mBGRARectProgram->CheckAndSetProjectionMatrix(matrix3d);
|
||||
|
||||
// Default blend function implements "OVER"
|
||||
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
|
||||
LOCAL_GL_ONE, LOCAL_GL_ONE);
|
||||
mGLContext->fEnable(LOCAL_GL_BLEND);
|
||||
|
||||
mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
mGLContext->fEnable(LOCAL_GL_TEXTURE_RECTANGLE_ARB);
|
||||
}
|
||||
|
||||
void
|
||||
GLPresenter::EndFrame()
|
||||
{
|
||||
mGLContext->SwapBuffers();
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation ChildView
|
||||
@ -3075,10 +3323,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
painted = mGeckoChild->PaintWindow(region);
|
||||
} else if (mGeckoChild->GetLayerManager()->GetBackendType() == LAYERS_CLIENT) {
|
||||
// We only need this so that we actually get DidPaintWindow fired
|
||||
if (Compositor::GetBackend() == LAYERS_BASIC) {
|
||||
ClientLayerManager *manager = static_cast<ClientLayerManager*>(mGeckoChild->GetLayerManager());
|
||||
manager->SetShadowTarget(targetContext);
|
||||
}
|
||||
painted = mGeckoChild->PaintWindow(region);
|
||||
}
|
||||
|
||||
|
@ -5973,6 +5973,24 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
nsWindow::StartRemoteDrawing()
|
||||
{
|
||||
gfxASurface *surf = GetThebesSurface();
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::IntSize size(surf->GetSize().width, surf->GetSize().height);
|
||||
if (size.width <= 0 || size.height <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
// return the gfxASurface for rendering to this widget
|
||||
gfxASurface*
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
|
@ -195,6 +195,10 @@ public:
|
||||
guint aTime,
|
||||
gpointer aData);
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void NativeResize(int32_t aWidth,
|
||||
int32_t aHeight,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
// forward declarations
|
||||
class nsFontMetrics;
|
||||
@ -47,6 +48,9 @@ class CompositorChild;
|
||||
class LayerManager;
|
||||
class PLayerTransactionChild;
|
||||
}
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,8 +96,8 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
||||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x5b9152, 0x56c8, 0x4a2d, \
|
||||
{ 0x94, 0x9e, 0xec, 0xf5, 0x3, 0x83, 0x3d, 0x48 } }
|
||||
{ 0xa2900e47, 0x0021, 0x441c, \
|
||||
{ 0x9e, 0x94, 0xd5, 0x61, 0x5a, 0x31, 0x5d, 0x7a } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -1192,6 +1196,31 @@ class nsIWidget : public nsISupports {
|
||||
*/
|
||||
virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) = 0;
|
||||
|
||||
/**
|
||||
* Return a DrawTarget for the window which can be composited into.
|
||||
*
|
||||
* Called by BasicCompositor on the compositor thread for OMTC drawing
|
||||
* before each composition.
|
||||
*/
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() = 0;
|
||||
|
||||
/**
|
||||
* Ensure that what was painted into the DrawTarget returned from
|
||||
* StartRemoteDrawing reaches the screen.
|
||||
*
|
||||
* Called by BasicCompositor on the compositor thread for OMTC drawing
|
||||
* after each composition.
|
||||
*/
|
||||
virtual void EndRemoteDrawing() = 0;
|
||||
|
||||
/**
|
||||
* Clean up any resources used by Start/EndRemoteDrawing.
|
||||
*
|
||||
* Called by BasicCompositor on the compositor thread for OMTC drawing
|
||||
* when the compositor is destroyed.
|
||||
*/
|
||||
virtual void CleanupRemoteDrawing() = 0;
|
||||
|
||||
/**
|
||||
* Called when Gecko knows which themed widgets exist in this window.
|
||||
* The passed array contains an entry for every themed widget of the right
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
@ -1031,6 +1032,11 @@ CompositorChild* nsBaseWidget::GetRemoteRenderer()
|
||||
return mCompositorChild;
|
||||
}
|
||||
|
||||
TemporaryRef<mozilla::gfx::DrawTarget> nsBaseWidget::StartRemoteDrawing()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Return the used device context
|
||||
|
@ -137,6 +137,9 @@ public:
|
||||
virtual void PreRender(LayerManager* aManager) {}
|
||||
virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) {}
|
||||
virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) {}
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing();
|
||||
virtual void EndRemoteDrawing() { };
|
||||
virtual void CleanupRemoteDrawing() { };
|
||||
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {}
|
||||
virtual gfxASurface* GetThebesSurface();
|
||||
NS_IMETHOD SetModal(bool aModal);
|
||||
|
Loading…
Reference in New Issue
Block a user