зеркало из https://github.com/mozilla/pjs.git
Bug 606910 - RENDER_DIRECT mode for Qt widget (xshmPutImage). r=dougt a=blocking-fennec
--HG-- extra : rebase_source : 6ea776ea7e0b282d6b61d5e5fa570460e84f90be
This commit is contained in:
Родитель
6d4b7edaf4
Коммит
35d0416872
|
@ -81,7 +81,11 @@
|
||||||
|
|
||||||
// Because the QPainter backend has some problems with glyphs rendering
|
// Because the QPainter backend has some problems with glyphs rendering
|
||||||
// it is better to use image or xlib cairo backends by default
|
// it is better to use image or xlib cairo backends by default
|
||||||
|
#if (MOZ_PLATFORM_MAEMO == 6)
|
||||||
#define DEFAULT_RENDER_MODE RENDER_BUFFERED
|
#define DEFAULT_RENDER_MODE RENDER_BUFFERED
|
||||||
|
#else
|
||||||
|
#define DEFAULT_RENDER_MODE RENDER_DIRECT
|
||||||
|
#endif
|
||||||
|
|
||||||
static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11;
|
static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11;
|
||||||
gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
|
gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
|
||||||
|
@ -146,6 +150,9 @@ gfxQtPlatform::gfxQtPlatform()
|
||||||
case 1:
|
case 1:
|
||||||
mRenderMode = RENDER_BUFFERED;
|
mRenderMode = RENDER_BUFFERED;
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
mRenderMode = RENDER_DIRECT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mRenderMode = RENDER_QPAINTER;
|
mRenderMode = RENDER_QPAINTER;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +214,7 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mRenderMode == RENDER_BUFFERED &&
|
if ((mRenderMode == RENDER_BUFFERED || mRenderMode == RENDER_DIRECT) &&
|
||||||
sDefaultQtPaintEngineType != QPaintEngine::X11) {
|
sDefaultQtPaintEngineType != QPaintEngine::X11) {
|
||||||
newSurface = new gfxImageSurface(size, imageFormat);
|
newSurface = new gfxImageSurface(size, imageFormat);
|
||||||
return newSurface.forget();
|
return newSurface.forget();
|
||||||
|
|
|
@ -60,6 +60,8 @@ public:
|
||||||
RENDER_QPAINTER = 0,
|
RENDER_QPAINTER = 0,
|
||||||
/* Use offscreen buffer for rendering with image or xlib gfx backend */
|
/* Use offscreen buffer for rendering with image or xlib gfx backend */
|
||||||
RENDER_BUFFERED,
|
RENDER_BUFFERED,
|
||||||
|
/* Direct rendering to Widget surface */
|
||||||
|
RENDER_DIRECT,
|
||||||
/* max */
|
/* max */
|
||||||
RENDER_MODE_MAX
|
RENDER_MODE_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,6 +135,8 @@ extern "C" {
|
||||||
#include "gfxXlibSurface.h"
|
#include "gfxXlibSurface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "nsShmImage.h"
|
||||||
|
|
||||||
#ifdef MOZ_DFB
|
#ifdef MOZ_DFB
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifdef MOZ_DIRECT_DEBUG
|
#ifdef MOZ_DIRECT_DEBUG
|
||||||
|
@ -286,16 +288,6 @@ UpdateLastInputEventTime()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_HAVE_SHMIMAGE
|
|
||||||
// If XShm isn't available to our client, we'll try XShm once, fail,
|
|
||||||
// set this to false and then never try again.
|
|
||||||
static PRBool gShmAvailable = PR_TRUE;
|
|
||||||
static PRBool UseShm()
|
|
||||||
{
|
|
||||||
return gfxPlatformGtk::UseClientSideRendering() && gShmAvailable;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this is the last window that had a drag event happen on it.
|
// this is the last window that had a drag event happen on it.
|
||||||
nsWindow *nsWindow::mLastDragMotionWindow = NULL;
|
nsWindow *nsWindow::mLastDragMotionWindow = NULL;
|
||||||
PRBool nsWindow::sIsDraggingOutOf = PR_FALSE;
|
PRBool nsWindow::sIsDraggingOutOf = PR_FALSE;
|
||||||
|
@ -389,159 +381,6 @@ protected:
|
||||||
pixman_region32& get() { return *this; }
|
pixman_region32& get() { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef MOZ_HAVE_SHMIMAGE
|
|
||||||
|
|
||||||
using mozilla::ipc::SharedMemorySysV;
|
|
||||||
|
|
||||||
class nsShmImage {
|
|
||||||
NS_INLINE_DECL_REFCOUNTING(nsShmImage)
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef gfxASurface::gfxImageFormat Format;
|
|
||||||
|
|
||||||
static already_AddRefed<nsShmImage>
|
|
||||||
Create(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth);
|
|
||||||
|
|
||||||
~nsShmImage() {
|
|
||||||
if (mImage) {
|
|
||||||
if (mXAttached) {
|
|
||||||
XShmDetach(gdk_x11_get_default_xdisplay(), &mInfo);
|
|
||||||
}
|
|
||||||
XDestroyImage(mImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<gfxASurface> AsSurface();
|
|
||||||
|
|
||||||
void Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd);
|
|
||||||
|
|
||||||
gfxIntSize Size() const { return mSize; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsShmImage()
|
|
||||||
: mImage(nsnull)
|
|
||||||
, mXAttached(PR_FALSE)
|
|
||||||
{ mInfo.shmid = SharedMemorySysV::NULLHandle(); }
|
|
||||||
|
|
||||||
nsRefPtr<SharedMemorySysV> mSegment;
|
|
||||||
XImage* mImage;
|
|
||||||
XShmSegmentInfo mInfo;
|
|
||||||
gfxIntSize mSize;
|
|
||||||
Format mFormat;
|
|
||||||
PRPackedBool mXAttached;
|
|
||||||
};
|
|
||||||
|
|
||||||
already_AddRefed<nsShmImage>
|
|
||||||
nsShmImage::Create(const gfxIntSize& aSize,
|
|
||||||
Visual* aVisual, unsigned int aDepth)
|
|
||||||
{
|
|
||||||
Display* dpy = gdk_x11_get_default_xdisplay();
|
|
||||||
|
|
||||||
nsRefPtr<nsShmImage> shm = new nsShmImage();
|
|
||||||
shm->mImage = XShmCreateImage(dpy, aVisual, aDepth,
|
|
||||||
ZPixmap, nsnull,
|
|
||||||
&(shm->mInfo),
|
|
||||||
aSize.width, aSize.height);
|
|
||||||
if (!shm->mImage) {
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = shm->mImage->bytes_per_line * shm->mImage->height;
|
|
||||||
shm->mSegment = new SharedMemorySysV();
|
|
||||||
if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) {
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
shm->mInfo.shmid = shm->mSegment->GetHandle();
|
|
||||||
shm->mInfo.shmaddr =
|
|
||||||
shm->mImage->data = static_cast<char*>(shm->mSegment->memory());
|
|
||||||
shm->mInfo.readOnly = False;
|
|
||||||
|
|
||||||
gdk_error_trap_push();
|
|
||||||
Status attachOk = XShmAttach(dpy, &shm->mInfo);
|
|
||||||
gint xerror = gdk_error_trap_pop();
|
|
||||||
|
|
||||||
if (!attachOk || xerror) {
|
|
||||||
// Assume XShm isn't available, and don't attempt to use it
|
|
||||||
// again.
|
|
||||||
gShmAvailable = PR_FALSE;
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
shm->mXAttached = PR_TRUE;
|
|
||||||
shm->mSize = aSize;
|
|
||||||
switch (shm->mImage->depth) {
|
|
||||||
case 24:
|
|
||||||
shm->mFormat = gfxASurface::ImageFormatRGB24; break;
|
|
||||||
case 16:
|
|
||||||
shm->mFormat = gfxASurface::ImageFormatRGB16_565; break;
|
|
||||||
default:
|
|
||||||
NS_WARNING("Unsupported XShm Image depth!");
|
|
||||||
gShmAvailable = PR_FALSE;
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
return shm.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<gfxASurface>
|
|
||||||
nsShmImage::AsSurface()
|
|
||||||
{
|
|
||||||
return nsRefPtr<gfxASurface>(
|
|
||||||
new gfxImageSurface(static_cast<unsigned char*>(mSegment->memory()),
|
|
||||||
mSize,
|
|
||||||
mImage->bytes_per_line,
|
|
||||||
mFormat)
|
|
||||||
).forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsShmImage::Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd)
|
|
||||||
{
|
|
||||||
GdkDrawable* gd;
|
|
||||||
gint dx, dy;
|
|
||||||
gdk_window_get_internal_paint_info(aWindow, &gd, &dx, &dy);
|
|
||||||
|
|
||||||
Display* dpy = gdk_x11_get_default_xdisplay();
|
|
||||||
Drawable d = GDK_DRAWABLE_XID(gd);
|
|
||||||
|
|
||||||
GC gc = XCreateGC(dpy, d, 0, nsnull);
|
|
||||||
for (GdkRectangle* r = aRects; r < aEnd; r++) {
|
|
||||||
XShmPutImage(dpy, d, gc, mImage,
|
|
||||||
r->x, r->y,
|
|
||||||
r->x - dx, r->y - dy,
|
|
||||||
r->width, r->height,
|
|
||||||
False);
|
|
||||||
}
|
|
||||||
XFreeGC(dpy, gc);
|
|
||||||
|
|
||||||
// FIXME/bug 597336: we need to ensure that the shm image isn't
|
|
||||||
// scribbled over before all its pending XShmPutImage()s complete.
|
|
||||||
// However, XSync() is an unnecessarily heavyweight
|
|
||||||
// synchronization mechanism; other options are possible. If this
|
|
||||||
// XSync is shown to hurt responsiveness, we need to explore the
|
|
||||||
// other options.
|
|
||||||
XSync(dpy, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
static already_AddRefed<gfxASurface>
|
|
||||||
EnsureShmImage(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth,
|
|
||||||
nsRefPtr<nsShmImage>& aImage)
|
|
||||||
{
|
|
||||||
if (!aImage || aImage->Size() != aSize) {
|
|
||||||
// Because we XSync() after XShmAttach() to trap errors, we
|
|
||||||
// know that the X server has the old image's memory mapped
|
|
||||||
// into its address space, so it's OK to destroy the old image
|
|
||||||
// here even if there are outstanding Puts. The Detach is
|
|
||||||
// ordered after the Puts.
|
|
||||||
aImage = nsShmImage::Create(aSize, aVisual, aDepth);
|
|
||||||
}
|
|
||||||
return !aImage ? nsnull : aImage->AsSurface();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
|
|
||||||
|
|
||||||
|
|
||||||
nsWindow::nsWindow()
|
nsWindow::nsWindow()
|
||||||
{
|
{
|
||||||
mIsTopLevel = PR_FALSE;
|
mIsTopLevel = PR_FALSE;
|
||||||
|
@ -2346,7 +2185,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
||||||
layerBuffering = BasicLayerManager::BUFFER_NONE;
|
layerBuffering = BasicLayerManager::BUFFER_NONE;
|
||||||
ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
ctx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||||
#ifdef MOZ_HAVE_SHMIMAGE
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
} else if (UseShm()) {
|
} else if (nsShmImage::UseShm()) {
|
||||||
// We're using an xshm mapping as a back buffer.
|
// We're using an xshm mapping as a back buffer.
|
||||||
layerBuffering = BasicLayerManager::BUFFER_NONE;
|
layerBuffering = BasicLayerManager::BUFFER_NONE;
|
||||||
#endif // MOZ_HAVE_SHMIMAGE
|
#endif // MOZ_HAVE_SHMIMAGE
|
||||||
|
@ -2405,7 +2244,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# ifdef MOZ_HAVE_SHMIMAGE
|
# ifdef MOZ_HAVE_SHMIMAGE
|
||||||
if (UseShm() && NS_LIKELY(!mIsDestroyed)) {
|
if (nsShmImage::UseShm() && NS_LIKELY(!mIsDestroyed)) {
|
||||||
mShmImage->Put(mGdkWindow, rects, r_end);
|
mShmImage->Put(mGdkWindow, rects, r_end);
|
||||||
}
|
}
|
||||||
# endif // MOZ_HAVE_SHMIMAGE
|
# endif // MOZ_HAVE_SHMIMAGE
|
||||||
|
@ -6706,13 +6545,14 @@ nsWindow::GetThebesSurface()
|
||||||
|
|
||||||
# ifdef MOZ_HAVE_SHMIMAGE
|
# ifdef MOZ_HAVE_SHMIMAGE
|
||||||
PRBool usingShm = PR_FALSE;
|
PRBool usingShm = PR_FALSE;
|
||||||
if (UseShm()) {
|
if (nsShmImage::UseShm()) {
|
||||||
// EnsureShmImage() is a dangerous interface, but we guarantee
|
// EnsureShmImage() is a dangerous interface, but we guarantee
|
||||||
// that the thebes surface and the shmimage have the same
|
// that the thebes surface and the shmimage have the same
|
||||||
// lifetime
|
// lifetime
|
||||||
mThebesSurface = EnsureShmImage(size,
|
mThebesSurface =
|
||||||
visual, gdk_drawable_get_depth(d),
|
nsShmImage::EnsureShmImage(size,
|
||||||
mShmImage);
|
visual, gdk_drawable_get_depth(d),
|
||||||
|
mShmImage);
|
||||||
usingShm = mThebesSurface != nsnull;
|
usingShm = mThebesSurface != nsnull;
|
||||||
}
|
}
|
||||||
if (!usingShm)
|
if (!usingShm)
|
||||||
|
|
|
@ -103,6 +103,8 @@ ifneq (qt,$(MOZ_WIDGET_TOOLKIT))
|
||||||
INACTIVE_COMPONENT = 1
|
INACTIVE_COMPONENT = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/config.mk
|
||||||
|
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
CXXFLAGS += $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
|
CXXFLAGS += $(MOZ_QT_CFLAGS) $(GLIB_CFLAGS) $(MOZ_CAIRO_CFLAGS)
|
||||||
|
@ -131,4 +133,5 @@ LOCAL_INCLUDES += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
ifdef MOZ_X11
|
ifdef MOZ_X11
|
||||||
INCLUDES += -I$(srcdir)/../shared/x11
|
INCLUDES += -I$(srcdir)/../shared/x11
|
||||||
|
INCLUDES += -I$(srcdir)/../shared
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -92,7 +92,7 @@ MozQWidget::~MozQWidget()
|
||||||
|
|
||||||
void MozQWidget::paint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget /*= 0*/)
|
void MozQWidget::paint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget /*= 0*/)
|
||||||
{
|
{
|
||||||
mReceiver->DoPaint(aPainter, aOption);
|
mReceiver->DoPaint(aPainter, aOption, aWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MozQWidget::activate()
|
void MozQWidget::activate()
|
||||||
|
|
|
@ -128,11 +128,22 @@ static const float GESTURES_BLOCK_MOUSE_FOR = 200;
|
||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
#include "LayerManagerOGL.h"
|
#include "LayerManagerOGL.h"
|
||||||
|
|
||||||
|
#include "nsShmImage.h"
|
||||||
|
extern "C" {
|
||||||
|
#include "pixman.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
// imported in nsWidgetFactory.cpp
|
// imported in nsWidgetFactory.cpp
|
||||||
PRBool gDisableNativeTheme = PR_FALSE;
|
PRBool gDisableNativeTheme = PR_FALSE;
|
||||||
|
|
||||||
// Cached offscreen surface
|
// Cached offscreen surface
|
||||||
static nsRefPtr<gfxASurface> gBufferSurface;
|
static nsRefPtr<gfxASurface> gBufferSurface;
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
// If we're using xshm rendering, mThebesSurface wraps gShmImage
|
||||||
|
nsRefPtr<nsShmImage> gShmImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int gBufferPixmapUsageCount = 0;
|
static int gBufferPixmapUsageCount = 0;
|
||||||
static gfxIntSize gBufferMaxSize(0, 0);
|
static gfxIntSize gBufferMaxSize(0, 0);
|
||||||
|
@ -268,7 +279,7 @@ _gfximage_to_qformat(gfxASurface::gfxImageFormat aFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
UpdateOffScreenBuffers(int aDepth, QSize aSize)
|
UpdateOffScreenBuffers(int aDepth, QSize aSize, QWidget* aWidget = nsnull)
|
||||||
{
|
{
|
||||||
gfxIntSize size(aSize.width(), aSize.height());
|
gfxIntSize size(aSize.width(), aSize.height());
|
||||||
if (gBufferSurface) {
|
if (gBufferSurface) {
|
||||||
|
@ -290,8 +301,22 @@ UpdateOffScreenBuffers(int aDepth, QSize aSize)
|
||||||
if (format == gfxASurface::ImageFormatUnknown)
|
if (format == gfxASurface::ImageFormatUnknown)
|
||||||
format = gfxASurface::ImageFormatRGB24;
|
format = gfxASurface::ImageFormatRGB24;
|
||||||
|
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
if (aWidget) {
|
||||||
|
if (gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType() ==
|
||||||
|
gfxASurface::SurfaceTypeImage) {
|
||||||
|
gShmImage = nsShmImage::Create(gBufferMaxSize,
|
||||||
|
(Visual*)aWidget->x11Info().visual(),
|
||||||
|
aDepth);
|
||||||
|
gBufferSurface = gShmImage->AsSurface();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gBufferSurface = gfxPlatform::GetPlatform()->
|
gBufferSurface = gfxPlatform::GetPlatform()->
|
||||||
CreateOffscreenSurface(gBufferMaxSize, gfxASurface::ContentFromFormat(format));
|
CreateOffscreenSurface(gBufferMaxSize, gfxASurface::ContentFromFormat(format));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +368,9 @@ nsWindow::Destroy(void)
|
||||||
--gBufferPixmapUsageCount == 0) {
|
--gBufferPixmapUsageCount == 0) {
|
||||||
|
|
||||||
gBufferSurface = nsnull;
|
gBufferSurface = nsnull;
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
gShmImage = nsnull;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
|
nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
|
||||||
|
@ -941,8 +969,23 @@ nsWindow::GetAttention(PRInt32 aCycleCount)
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_X11
|
||||||
|
static already_AddRefed<gfxASurface>
|
||||||
|
GetSurfaceForQWidget(QWidget* aDrawable)
|
||||||
|
{
|
||||||
|
gfxASurface* result =
|
||||||
|
new gfxXlibSurface(aDrawable->x11Info().display(),
|
||||||
|
aDrawable->handle(),
|
||||||
|
(Visual*)aDrawable->x11Info().visual(),
|
||||||
|
gfxIntSize(aDrawable->size().width(),
|
||||||
|
aDrawable->size().height()));
|
||||||
|
NS_IF_ADDREF(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
nsEventStatus
|
nsEventStatus
|
||||||
nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget)
|
||||||
{
|
{
|
||||||
if (mIsDestroyed) {
|
if (mIsDestroyed) {
|
||||||
LOG(("Expose event on destroyed window [%p] window %p\n",
|
LOG(("Expose event on destroyed window [%p] window %p\n",
|
||||||
|
@ -993,6 +1036,11 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||||
} else if (renderMode == gfxQtPlatform::RENDER_QPAINTER) {
|
} else if (renderMode == gfxQtPlatform::RENDER_QPAINTER) {
|
||||||
targetSurface = new gfxQPainterSurface(aPainter);
|
targetSurface = new gfxQPainterSurface(aPainter);
|
||||||
#endif
|
#endif
|
||||||
|
} else if (renderMode == gfxQtPlatform::RENDER_DIRECT) {
|
||||||
|
if (!UpdateOffScreenBuffers(depth, aWidget->size(), aWidget)) {
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
targetSurface = gBufferSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_UNLIKELY(!targetSurface))
|
if (NS_UNLIKELY(!targetSurface))
|
||||||
|
@ -1001,17 +1049,30 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
|
nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
|
||||||
|
|
||||||
// We will paint to 0, 0 position in offscrenn buffer
|
// We will paint to 0, 0 position in offscrenn buffer
|
||||||
if (renderMode == gfxQtPlatform::RENDER_BUFFERED)
|
if (renderMode == gfxQtPlatform::RENDER_BUFFERED) {
|
||||||
ctx->Translate(gfxPoint(-r.x(), -r.y()));
|
ctx->Translate(gfxPoint(-r.x(), -r.y()));
|
||||||
|
}
|
||||||
|
else if (renderMode == gfxQtPlatform::RENDER_DIRECT) {
|
||||||
|
// This is needed for rotate transformation on Meego
|
||||||
|
// This will work very slow if pixman does not handle rotation very well
|
||||||
|
gfxMatrix matr(aPainter->transform().m11(),
|
||||||
|
aPainter->transform().m12(),
|
||||||
|
aPainter->transform().m21(),
|
||||||
|
aPainter->transform().m22(),
|
||||||
|
aPainter->transform().dx(),
|
||||||
|
aPainter->transform().dy());
|
||||||
|
ctx->SetMatrix(matr);
|
||||||
|
NS_ASSERTION(PIXMAN_VERSION < PIXMAN_VERSION_ENCODE(0, 21, 2) && aPainter->transform().isRotating(), "Old pixman and rotate transform, it is going to be slow");
|
||||||
|
}
|
||||||
|
|
||||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||||
event.refPoint.x = r.x();
|
event.refPoint.x = rect.x;
|
||||||
event.refPoint.y = r.y();
|
event.refPoint.y = rect.y;
|
||||||
event.region = nsIntRegion(rect);
|
event.region = nsIntRegion(rect);
|
||||||
{
|
{
|
||||||
AutoLayerManagerSetup
|
AutoLayerManagerSetup
|
||||||
setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
|
setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
|
||||||
status = DispatchEvent(&event);
|
status = DispatchEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchEvent can Destroy us (bug 378273), avoid doing any paint
|
// DispatchEvent can Destroy us (bug 378273), avoid doing any paint
|
||||||
|
@ -1047,6 +1108,30 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||||
aPainter->drawImage(QPoint(rect.x, rect.y), img,
|
aPainter->drawImage(QPoint(rect.x, rect.y), img,
|
||||||
QRect(0, 0, rect.width, rect.height));
|
QRect(0, 0, rect.width, rect.height));
|
||||||
}
|
}
|
||||||
|
} else if (renderMode == gfxQtPlatform::RENDER_DIRECT) {
|
||||||
|
QRect trans = aPainter->transform().mapRect(r).toRect();
|
||||||
|
if (gBufferSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||||
|
nsRefPtr<gfxASurface> widgetSurface = GetSurfaceForQWidget(aWidget);
|
||||||
|
nsRefPtr<gfxContext> ctx = new gfxContext(widgetSurface);
|
||||||
|
ctx->SetSource(gBufferSurface);
|
||||||
|
ctx->Rectangle(gfxRect(trans.x(), trans.y(), trans.width(), trans.height()), PR_TRUE);
|
||||||
|
ctx->Clip();
|
||||||
|
ctx->Fill();
|
||||||
|
} else if (gBufferSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
if (gShmImage) {
|
||||||
|
gShmImage->Put(aWidget, trans);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (gBufferSurface) {
|
||||||
|
nsRefPtr<gfxASurface> widgetSurface = GetSurfaceForQWidget(aWidget);
|
||||||
|
nsRefPtr<gfxContext> ctx = new gfxContext(widgetSurface);
|
||||||
|
ctx->SetSource(gBufferSurface);
|
||||||
|
ctx->Rectangle(gfxRect(trans.x(), trans.y(), trans.width(), trans.height()), PR_TRUE);
|
||||||
|
ctx->Clip();
|
||||||
|
ctx->Fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = nsnull;
|
ctx = nsnull;
|
||||||
|
@ -2475,6 +2560,11 @@ nsWindow::createQWidget(MozQWidget *parent, nsWidgetInitData *aInitData)
|
||||||
newView->setViewport(new QGLWidget());
|
newView->setViewport(new QGLWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gfxQtPlatform::GetPlatform()->GetRenderMode() == gfxQtPlatform::RENDER_DIRECT) {
|
||||||
|
// Disable double buffer and system background rendering
|
||||||
|
newView->viewport()->setAttribute(Qt::WA_PaintOnScreen, true);
|
||||||
|
newView->viewport()->setAttribute(Qt::WA_NoSystemBackground, true);
|
||||||
|
}
|
||||||
// Enable gestures:
|
// Enable gestures:
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
|
||||||
newView->viewport()->grabGesture(Qt::PinchGesture);
|
newView->viewport()->grabGesture(Qt::PinchGesture);
|
||||||
|
@ -2528,8 +2618,8 @@ nsWindow::GetThebesSurface()
|
||||||
if (mThebesSurface)
|
if (mThebesSurface)
|
||||||
return mThebesSurface;
|
return mThebesSurface;
|
||||||
|
|
||||||
gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
|
|
||||||
#ifdef CAIRO_HAS_QT_SURFACE
|
#ifdef CAIRO_HAS_QT_SURFACE
|
||||||
|
gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
|
||||||
if (renderMode == gfxQtPlatform::RENDER_QPAINTER) {
|
if (renderMode == gfxQtPlatform::RENDER_QPAINTER) {
|
||||||
mThebesSurface = new gfxQPainterSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR);
|
mThebesSurface = new gfxQPainterSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
nsWindow();
|
nsWindow();
|
||||||
virtual ~nsWindow();
|
virtual ~nsWindow();
|
||||||
|
|
||||||
nsEventStatus DoPaint( QPainter* aPainter, const QStyleOptionGraphicsItem * aOption );
|
nsEventStatus DoPaint( QPainter* aPainter, const QStyleOptionGraphicsItem * aOption, QWidget* aWidget);
|
||||||
|
|
||||||
static void ReleaseGlobals();
|
static void ReleaseGlobals();
|
||||||
|
|
||||||
|
|
|
@ -57,12 +57,14 @@ endif
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
WidgetUtils.cpp \
|
WidgetUtils.cpp \
|
||||||
|
nsShmImage.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||||
FORCE_STATIC_LIB = 1
|
FORCE_STATIC_LIB = 1
|
||||||
|
|
||||||
include $(topsrcdir)/config/config.mk
|
include $(topsrcdir)/config/config.mk
|
||||||
|
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
CXXFLAGS += $(TK_CFLAGS)
|
CXXFLAGS += $(TK_CFLAGS)
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; 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 the Mozilla browser.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Jones <jones.chris.g@gmail.com>
|
||||||
|
* Oleg Romashin <romaxa@gmail.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 ***** */
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#elif defined(MOZ_WIDGET_QT)
|
||||||
|
#include <QWidget>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nsShmImage.h"
|
||||||
|
#include "gfxPlatform.h"
|
||||||
|
#include "gfxImageSurface.h"
|
||||||
|
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
|
||||||
|
// If XShm isn't available to our client, we'll try XShm once, fail,
|
||||||
|
// set this to false and then never try again.
|
||||||
|
static PRBool gShmAvailable = PR_TRUE;
|
||||||
|
PRBool nsShmImage::UseShm()
|
||||||
|
{
|
||||||
|
return gfxPlatform::GetPlatform()->
|
||||||
|
ScreenReferenceSurface()->GetType() == gfxASurface::SurfaceTypeImage
|
||||||
|
&& gShmAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsShmImage>
|
||||||
|
nsShmImage::Create(const gfxIntSize& aSize,
|
||||||
|
Visual* aVisual, unsigned int aDepth)
|
||||||
|
{
|
||||||
|
Display* dpy = DISPLAY();
|
||||||
|
|
||||||
|
nsRefPtr<nsShmImage> shm = new nsShmImage();
|
||||||
|
shm->mImage = XShmCreateImage(dpy, aVisual, aDepth,
|
||||||
|
ZPixmap, nsnull,
|
||||||
|
&(shm->mInfo),
|
||||||
|
aSize.width, aSize.height);
|
||||||
|
if (!shm->mImage) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = shm->mImage->bytes_per_line * shm->mImage->height;
|
||||||
|
shm->mSegment = new SharedMemorySysV();
|
||||||
|
if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm->mInfo.shmid = shm->mSegment->GetHandle();
|
||||||
|
shm->mInfo.shmaddr =
|
||||||
|
shm->mImage->data = static_cast<char*>(shm->mSegment->memory());
|
||||||
|
shm->mInfo.readOnly = False;
|
||||||
|
|
||||||
|
int xerror = 0;
|
||||||
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
|
gdk_error_trap_push();
|
||||||
|
Status attachOk = XShmAttach(dpy, &shm->mInfo);
|
||||||
|
xerror = gdk_error_trap_pop();
|
||||||
|
#elif defined(MOZ_WIDGET_QT)
|
||||||
|
Status attachOk = XShmAttach(dpy, &shm->mInfo);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!attachOk || xerror) {
|
||||||
|
// Assume XShm isn't available, and don't attempt to use it
|
||||||
|
// again.
|
||||||
|
gShmAvailable = PR_FALSE;
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm->mXAttached = PR_TRUE;
|
||||||
|
shm->mSize = aSize;
|
||||||
|
switch (shm->mImage->depth) {
|
||||||
|
case 24:
|
||||||
|
shm->mFormat = gfxASurface::ImageFormatRGB24; break;
|
||||||
|
case 16:
|
||||||
|
shm->mFormat = gfxASurface::ImageFormatRGB16_565; break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Unsupported XShm Image depth!");
|
||||||
|
gShmAvailable = PR_FALSE;
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
return shm.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<gfxASurface>
|
||||||
|
nsShmImage::AsSurface()
|
||||||
|
{
|
||||||
|
return nsRefPtr<gfxASurface>(
|
||||||
|
new gfxImageSurface(static_cast<unsigned char*>(mSegment->memory()),
|
||||||
|
mSize,
|
||||||
|
mImage->bytes_per_line,
|
||||||
|
mFormat)
|
||||||
|
).forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
|
void
|
||||||
|
nsShmImage::Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd)
|
||||||
|
{
|
||||||
|
GdkDrawable* gd;
|
||||||
|
gint dx, dy;
|
||||||
|
gdk_window_get_internal_paint_info(aWindow, &gd, &dx, &dy);
|
||||||
|
|
||||||
|
Display* dpy = gdk_x11_get_default_xdisplay();
|
||||||
|
Drawable d = GDK_DRAWABLE_XID(gd);
|
||||||
|
|
||||||
|
GC gc = XCreateGC(dpy, d, 0, nsnull);
|
||||||
|
for (GdkRectangle* r = aRects; r < aEnd; r++) {
|
||||||
|
XShmPutImage(dpy, d, gc, mImage,
|
||||||
|
r->x, r->y,
|
||||||
|
r->x - dx, r->y - dy,
|
||||||
|
r->width, r->height,
|
||||||
|
False);
|
||||||
|
}
|
||||||
|
XFreeGC(dpy, gc);
|
||||||
|
|
||||||
|
#ifdef MOZ_WIDGET_GTK2
|
||||||
|
// FIXME/bug 597336: we need to ensure that the shm image isn't
|
||||||
|
// scribbled over before all its pending XShmPutImage()s complete.
|
||||||
|
// However, XSync() is an unnecessarily heavyweight
|
||||||
|
// synchronization mechanism; other options are possible. If this
|
||||||
|
// XSync is shown to hurt responsiveness, we need to explore the
|
||||||
|
// other options.
|
||||||
|
XSync(dpy, False);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#elif defined(MOZ_WIDGET_QT)
|
||||||
|
void
|
||||||
|
nsShmImage::Put(QWidget* aWindow, QRect& aRect)
|
||||||
|
{
|
||||||
|
Display* dpy = aWindow->x11Info().display();
|
||||||
|
Drawable d = aWindow->handle();
|
||||||
|
|
||||||
|
GC gc = XCreateGC(dpy, d, 0, nsnull);
|
||||||
|
// Avoid out of bounds painting
|
||||||
|
QRect inter = aRect.intersected(aWindow->rect());
|
||||||
|
XShmPutImage(dpy, d, gc, mImage,
|
||||||
|
inter.x(), inter.y(),
|
||||||
|
inter.x(), inter.y(),
|
||||||
|
inter.width(), inter.height(),
|
||||||
|
False);
|
||||||
|
XFreeGC(dpy, gc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
already_AddRefed<gfxASurface>
|
||||||
|
nsShmImage::EnsureShmImage(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth,
|
||||||
|
nsRefPtr<nsShmImage>& aImage)
|
||||||
|
{
|
||||||
|
if (!aImage || aImage->Size() != aSize) {
|
||||||
|
// Because we XSync() after XShmAttach() to trap errors, we
|
||||||
|
// know that the X server has the old image's memory mapped
|
||||||
|
// into its address space, so it's OK to destroy the old image
|
||||||
|
// here even if there are outstanding Puts. The Detach is
|
||||||
|
// ordered after the Puts.
|
||||||
|
aImage = nsShmImage::Create(aSize, aVisual, aDepth);
|
||||||
|
}
|
||||||
|
return !aImage ? nsnull : aImage->AsSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
|
|
@ -0,0 +1,122 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; 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 the Mozilla browser.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Jones <jones.chris.g@gmail.com>
|
||||||
|
* Oleg Romashin <romaxa@gmail.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 ***** */
|
||||||
|
|
||||||
|
#ifndef __mozilla_widget_nsShmImage_h__
|
||||||
|
#define __mozilla_widget_nsShmImage_h__
|
||||||
|
|
||||||
|
#ifdef MOZ_IPC
|
||||||
|
# include "mozilla/ipc/SharedMemorySysV.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
|
||||||
|
# define MOZ_HAVE_SHMIMAGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_HAVE_SHMIMAGE
|
||||||
|
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "gfxASurface.h"
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/extensions/XShm.h>
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
|
#define DISPLAY gdk_x11_get_default_xdisplay
|
||||||
|
#elif defined(MOZ_WIDGET_QT)
|
||||||
|
#include "QX11Info"
|
||||||
|
#define DISPLAY QX11Info().display
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QRect;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
using mozilla::ipc::SharedMemorySysV;
|
||||||
|
|
||||||
|
class nsShmImage {
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(nsShmImage)
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef gfxASurface::gfxImageFormat Format;
|
||||||
|
|
||||||
|
static PRBool UseShm();
|
||||||
|
static already_AddRefed<nsShmImage>
|
||||||
|
Create(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth);
|
||||||
|
static already_AddRefed<gfxASurface>
|
||||||
|
EnsureShmImage(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth,
|
||||||
|
nsRefPtr<nsShmImage>& aImage);
|
||||||
|
|
||||||
|
~nsShmImage() {
|
||||||
|
if (mImage) {
|
||||||
|
XSync(DISPLAY(), False);
|
||||||
|
if (mXAttached) {
|
||||||
|
XShmDetach(DISPLAY(), &mInfo);
|
||||||
|
}
|
||||||
|
XDestroyImage(mImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<gfxASurface> AsSurface();
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GTK2)
|
||||||
|
void Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd);
|
||||||
|
#elif defined(MOZ_WIDGET_QT)
|
||||||
|
void Put(QWidget* aWindow, QRect& aRect);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gfxIntSize Size() const { return mSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsShmImage()
|
||||||
|
: mImage(nsnull)
|
||||||
|
, mXAttached(PR_FALSE)
|
||||||
|
{ mInfo.shmid = SharedMemorySysV::NULLHandle(); }
|
||||||
|
|
||||||
|
nsRefPtr<SharedMemorySysV> mSegment;
|
||||||
|
XImage* mImage;
|
||||||
|
XShmSegmentInfo mInfo;
|
||||||
|
gfxIntSize mSize;
|
||||||
|
Format mFormat;
|
||||||
|
PRPackedBool mXAttached;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MOZ_HAVE_SHMIMAGE
|
||||||
|
|
||||||
|
#endif
|
Загрузка…
Ссылка в новой задаче