mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 561772 - Simplify Qt rendering modes and remove dependency from gfxSharedImageSurface. r=joe.
--HG-- extra : rebase_source : d42def8318eb068571f0a5db515593d7f99a56c0
This commit is contained in:
parent
9cbb1c5d7b
commit
fef66108af
@ -58,8 +58,8 @@ public:
|
||||
enum RenderMode {
|
||||
/* Use QPainter surfaces */
|
||||
RENDER_QPAINTER = 0,
|
||||
/* Use image surfaces and XShmPutImage to QPixmap */
|
||||
RENDER_SHARED_IMAGE,
|
||||
/* Use offscreen buffer for rendering with image or xlib gfx backend */
|
||||
RENDER_BUFFERED,
|
||||
/* max */
|
||||
RENDER_MODE_MAX
|
||||
};
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <QX11Info>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QPaintEngine>
|
||||
|
||||
#include "gfxQtPlatform.h"
|
||||
|
||||
@ -78,8 +79,11 @@
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
|
||||
#define DEFAULT_RENDER_MODE RENDER_SHARED_IMAGE
|
||||
// Because the QPainter backend has some problems with glyphs rendering
|
||||
// it is better to use image or xlib cairo backends by default
|
||||
#define DEFAULT_RENDER_MODE RENDER_BUFFERED
|
||||
|
||||
static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11;
|
||||
gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
|
||||
static cairo_user_data_key_t cairo_qt_pixmap_key;
|
||||
static void do_qt_pixmap_unref (void *data)
|
||||
@ -140,11 +144,16 @@ gfxQtPlatform::gfxQtPlatform()
|
||||
mRenderMode = RENDER_QPAINTER;
|
||||
break;
|
||||
case 1:
|
||||
mRenderMode = RENDER_SHARED_IMAGE;
|
||||
mRenderMode = RENDER_BUFFERED;
|
||||
break;
|
||||
default:
|
||||
mRenderMode = RENDER_QPAINTER;
|
||||
}
|
||||
|
||||
// Qt doesn't provide a public API to detect the graphicssystem type. We hack
|
||||
// around this by checking what type of graphicssystem a test QPixmap uses.
|
||||
QPixmap pixmap(1, 1);
|
||||
sDefaultQtPaintEngineType = pixmap.paintEngine()->type();
|
||||
}
|
||||
|
||||
gfxQtPlatform::~gfxQtPlatform()
|
||||
@ -190,7 +199,8 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size,
|
||||
return newSurface.forget();
|
||||
}
|
||||
|
||||
if (mRenderMode == RENDER_SHARED_IMAGE) {
|
||||
if (mRenderMode == RENDER_BUFFERED &&
|
||||
sDefaultQtPaintEngineType != QPaintEngine::X11) {
|
||||
newSurface = new gfxImageSurface(size, imageFormat);
|
||||
return newSurface.forget();
|
||||
}
|
||||
|
@ -94,7 +94,7 @@
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "gfxQPainterSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#include "nsIDOMSimpleGestureEvent.h" //Gesture support
|
||||
|
||||
@ -105,9 +105,8 @@ PRBool gDisableNativeTheme = PR_FALSE;
|
||||
static QPixmap *gBufferPixmap = nsnull;
|
||||
static int gBufferPixmapUsageCount = 0;
|
||||
|
||||
// Buffered shared image + pixmap
|
||||
static gfxSharedImageSurface *gBufferImage = nsnull;
|
||||
static gfxSharedImageSurface *gBufferImageTemp = nsnull;
|
||||
// Buffered image + pixmap
|
||||
static gfxImageSurface *gBufferImage = nsnull;
|
||||
static gfxIntSize gBufferMaxSize(0, 0);
|
||||
|
||||
/* For PrepareNativeWidget */
|
||||
@ -217,15 +216,12 @@ _depth_to_gfximage_format(PRInt32 aDepth)
|
||||
}
|
||||
|
||||
static inline QImage::Format
|
||||
_depth_to_qformat(PRInt32 aDepth)
|
||||
_gfximage_to_qformat(gfxASurface::gfxImageFormat aFormat)
|
||||
{
|
||||
switch (aDepth) {
|
||||
case 32:
|
||||
switch (aFormat) {
|
||||
case gfxASurface::ImageFormatARGB32:
|
||||
case gfxASurface::ImageFormatRGB24:
|
||||
return QImage::Format_ARGB32;
|
||||
case 24:
|
||||
return QImage::Format_RGB32;
|
||||
case 16:
|
||||
return QImage::Format_RGB16;
|
||||
default:
|
||||
return QImage::Format_Invalid;
|
||||
}
|
||||
@ -235,10 +231,8 @@ static void
|
||||
FreeOffScreenBuffers(void)
|
||||
{
|
||||
delete gBufferImage;
|
||||
delete gBufferImageTemp;
|
||||
delete gBufferPixmap;
|
||||
gBufferImage = nsnull;
|
||||
gBufferImageTemp = nsnull;
|
||||
gBufferPixmap = nsnull;
|
||||
}
|
||||
|
||||
@ -256,50 +250,22 @@ UpdateOffScreenBuffers(QPaintEngine::Type aType, int aDepth, QSize aSize)
|
||||
|
||||
gBufferMaxSize.width = PR_MAX(gBufferMaxSize.width, size.width);
|
||||
gBufferMaxSize.height = PR_MAX(gBufferMaxSize.height, size.height);
|
||||
// For Qt X11 engine better to use QPixmap as offscreen buffer
|
||||
if (aType == QPaintEngine::X11) {
|
||||
gBufferPixmap = new QPixmap(gBufferMaxSize.width, gBufferMaxSize.height);
|
||||
if (!gBufferPixmap)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if system depth has related gfxImage format
|
||||
gfxASurface::gfxImageFormat format =
|
||||
_depth_to_gfximage_format(aDepth);
|
||||
PRBool depthFormatInCompatible = (format == gfxASurface::ImageFormatUnknown);
|
||||
|
||||
// In raster backend we don't care about incompatible mode, and will paint in
|
||||
// default RGB24 format... Raster engine will convert it to target color depth
|
||||
if (depthFormatInCompatible && aType == QPaintEngine::Raster) {
|
||||
depthFormatInCompatible = PR_FALSE;
|
||||
// Use fallback RGB24 format, Qt will do conversion for us
|
||||
if (format == gfxASurface::ImageFormatUnknown)
|
||||
format = gfxASurface::ImageFormatRGB24;
|
||||
}
|
||||
|
||||
gBufferImage = new gfxSharedImageSurface();
|
||||
if (!gBufferImage) {
|
||||
FreeOffScreenBuffers();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gBufferImage->Init(gBufferMaxSize, format, aDepth)) {
|
||||
FreeOffScreenBuffers();
|
||||
return false;
|
||||
}
|
||||
|
||||
// gfxImageSurface does not support system color depth format
|
||||
// we have to paint it with temp surface and color conversion
|
||||
if (!depthFormatInCompatible)
|
||||
return true;
|
||||
|
||||
gBufferImageTemp = new gfxSharedImageSurface();
|
||||
if (!gBufferImageTemp) {
|
||||
FreeOffScreenBuffers();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gBufferImageTemp->Init(gBufferMaxSize, gfxASurface::ImageFormatRGB24)) {
|
||||
FreeOffScreenBuffers();
|
||||
return false;
|
||||
}
|
||||
// For non-X11 qt paint engine we use image surface as offscreen buffer
|
||||
gBufferImage = new gfxImageSurface(gBufferMaxSize, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -998,6 +964,20 @@ nsWindow::GetAttention(PRInt32 aCycleCount)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#ifdef MOZ_X11
|
||||
static already_AddRefed<gfxASurface>
|
||||
GetSurfaceForQPixmap(QPixmap* 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
|
||||
nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||
{
|
||||
@ -1025,15 +1005,20 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||
gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
|
||||
QPaintEngine::Type paintEngineType = aPainter->paintEngine()->type();
|
||||
int depth = aPainter->device()->depth();
|
||||
// Prepare offscreen buffers if RenderMode Xlib or Image
|
||||
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE)
|
||||
|
||||
nsRefPtr<gfxASurface> targetSurface = nsnull;
|
||||
if (renderMode == gfxQtPlatform::RENDER_BUFFERED) {
|
||||
// Prepare offscreen buffers iamge or xlib, depends from paintEngineType
|
||||
if (!UpdateOffScreenBuffers(paintEngineType, depth, QSize(r.width(), r.height())))
|
||||
return nsEventStatus_eIgnore;
|
||||
|
||||
nsRefPtr<gfxASurface> targetSurface = nsnull;
|
||||
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE) {
|
||||
targetSurface = gBufferImageTemp ? gBufferImageTemp->getASurface()
|
||||
: gBufferImage->getASurface();
|
||||
if (paintEngineType == QPaintEngine::X11) {
|
||||
targetSurface = GetSurfaceForQPixmap(gBufferPixmap);
|
||||
}
|
||||
else if (paintEngineType == QPaintEngine::Raster) {
|
||||
NS_ADDREF(targetSurface = gBufferImage);
|
||||
}
|
||||
|
||||
} else if (renderMode == gfxQtPlatform::RENDER_QPAINTER) {
|
||||
targetSurface = new gfxQPainterSurface(aPainter);
|
||||
}
|
||||
@ -1044,7 +1029,7 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
|
||||
|
||||
// We will paint to 0, 0 position in offscrenn buffer
|
||||
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE)
|
||||
if (renderMode == gfxQtPlatform::RENDER_BUFFERED)
|
||||
ctx->Translate(gfxPoint(-r.x(), -r.y()));
|
||||
|
||||
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
|
||||
@ -1070,36 +1055,9 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||
|
||||
LOGDRAW(("[%p] draw done\n", this));
|
||||
|
||||
// Handle not direct painting mode
|
||||
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE) {
|
||||
// Handle buffered painting mode
|
||||
if (renderMode == gfxQtPlatform::RENDER_BUFFERED) {
|
||||
if (paintEngineType == QPaintEngine::X11) {
|
||||
// When Qt is working in X11 mode, then we should put our shared image to X
|
||||
if (gBufferImageTemp && gBufferImage) {
|
||||
// If gBufferImageTemp no null, then we have incompatible QPaintDevice color format
|
||||
// Need to convert first
|
||||
QImage src_img(gBufferImageTemp->Data(),
|
||||
gBufferImageTemp->Width(),
|
||||
gBufferImageTemp->Height(),
|
||||
gBufferImageTemp->Stride(),
|
||||
_depth_to_qformat(gBufferImageTemp->Depth()));
|
||||
QImage dst_img(gBufferImage->Data(),
|
||||
gBufferImage->Width(),
|
||||
gBufferImage->Height(),
|
||||
gBufferImage->Stride(),
|
||||
_depth_to_qformat(gBufferImage->Depth()));
|
||||
QPainter p(&dst_img);
|
||||
p.drawImage(QPoint(0, 0), src_img, QRect(0, 0, rect.width, rect.height));
|
||||
}
|
||||
|
||||
Display *disp = gBufferPixmap->x11Info().display();
|
||||
XGCValues gcv;
|
||||
gcv.graphics_exposures = False;
|
||||
GC gc = XCreateGC(disp, gBufferPixmap->handle(), GCGraphicsExposures, &gcv);
|
||||
XShmPutImage(disp, gBufferPixmap->handle(), gc, gBufferImage->image(),
|
||||
0, 0, 0, 0, rect.width, rect.height,
|
||||
False);
|
||||
XSync(disp, False);
|
||||
XFreeGC(disp, gc);
|
||||
// Paint offscreen pixmap to QPainter
|
||||
aPainter->drawPixmap(QPoint(rect.x, rect.y), *gBufferPixmap,
|
||||
QRect(0, 0, rect.width, rect.height));
|
||||
@ -1110,7 +1068,7 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
|
||||
gBufferImage->Width(),
|
||||
gBufferImage->Height(),
|
||||
gBufferImage->Stride(),
|
||||
_depth_to_qformat(gBufferImage->Depth()));
|
||||
_gfximage_to_qformat(gBufferImage->Format()));
|
||||
aPainter->drawImage(QPoint(rect.x, rect.y), img,
|
||||
QRect(0, 0, rect.width, rect.height));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user