diff options
Diffstat (limited to 'src')
59 files changed, 1850 insertions, 864 deletions
diff --git a/src/3rdparty/README b/src/3rdparty/README index 2be1036..ef05674 100644 --- a/src/3rdparty/README +++ b/src/3rdparty/README @@ -20,3 +20,8 @@ have been removed: Some patches are applied from time to time. Recent patches can be found in the patches subdirectory. + + +The pvr2d.h & wsegl.h in the powervr directory are required for building +the PowerVR plugin on Qt for Embedded Linux. These headers are for SGX +based SoCs, but may also work on MBX SoCs. diff --git a/src/3rdparty/powervr/pvr2d.h b/src/3rdparty/powervr/pvr2d.h new file mode 100644 index 0000000..07f28c7 --- /dev/null +++ b/src/3rdparty/powervr/pvr2d.h @@ -0,0 +1,502 @@ +/*!**************************************************************************** +@File pvr2d.h +@Title PVR2D external header file +@Author Imagination Technologies +@Copyright Copyright (c) by Imagination Technologies Limited. + This specification is protected by copyright laws and contains + material proprietary to Imagination Technologies Limited. + You may use and distribute this specification free of charge for implementing + the functionality therein, without altering or removing any trademark, copyright, + or other notice from the specification. +@Platform Generic +@Description PVR2D definitions for PVR2D clients +******************************************************************************/ + + +/****************************************************************************** +Modifications :- +$Log: pvr2d.h $ +******************************************************************************/ + +#ifndef _PVR2D_H_ +#define _PVR2D_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* PVR2D Platform-specific definitions */ +#define PVR2D_EXPORT +#define PVR2D_IMPORT + + +#define PVR2D_REV_MAJOR 2 +#define PVR2D_REV_MINOR 1 + +typedef enum +{ + PVR2D_FALSE = 0, + PVR2D_TRUE +} PVR2D_BOOL; + + +/* error codes */ +typedef enum +{ + PVR2D_OK = 0, + PVR2DERROR_INVALID_PARAMETER = -1, + PVR2DERROR_DEVICE_UNAVAILABLE = -2, + PVR2DERROR_INVALID_CONTEXT = -3, + PVR2DERROR_MEMORY_UNAVAILABLE = -4, + PVR2DERROR_DEVICE_NOT_PRESENT = -5, + PVR2DERROR_IOCTL_ERROR = -6, + PVR2DERROR_GENERIC_ERROR = -7, + PVR2DERROR_BLT_NOTCOMPLETE = -8, + PVR2DERROR_HW_FEATURE_NOT_SUPPORTED = -9, + PVR2DERROR_NOT_YET_IMPLEMENTED = -10, + PVR2DERROR_MAPPING_FAILED = -11 +}PVR2DERROR; + + +/* pixel formats */ +typedef enum +{ + PVR2D_1BPP = 0, + PVR2D_RGB565, + PVR2D_ARGB4444, + PVR2D_RGB888, + PVR2D_ARGB8888, + PVR2D_ARGB1555, + PVR2D_ALPHA8, + PVR2D_ALPHA4, + PVR2D_PAL2, + PVR2D_PAL4, + PVR2D_PAL8, + PVR2D_VGAEMU + +}PVR2DFORMAT; + + +/* wrap surface type */ +typedef enum +{ + PVR2D_WRAPFLAG_NONCONTIGUOUS = 0, + PVR2D_WRAPFLAG_CONTIGUOUS = 1, + +}PVR2DWRAPFLAGS; + +/* flags for control information of additional blits */ +typedef enum +{ + PVR2D_BLIT_DISABLE_ALL = 0x0000, /* disable all additional controls */ + PVR2D_BLIT_CK_ENABLE = 0x0001, /* enable colour key */ + PVR2D_BLIT_GLOBAL_ALPHA_ENABLE = 0x0002, /* enable standard global alpha */ + PVR2D_BLIT_PERPIXEL_ALPHABLEND_ENABLE = 0x0004, /* enable per-pixel alpha bleding */ + PVR2D_BLIT_PAT_SURFACE_ENABLE = 0x0008, /* enable pattern surf (disable fill) */ + PVR2D_BLIT_FULLY_SPECIFIED_ALPHA_ENABLE = 0x0010, /* enable fully specified alpha */ + PVR2D_BLIT_ROT_90 = 0x0020, /* apply 90 degree rotation to the blt */ + PVR2D_BLIT_ROT_180 = 0x0040, /* apply 180 degree rotation to the blt */ + PVR2D_BLIT_ROT_270 = 0x0080, /* apply 270 degree rotation to the blt */ + PVR2D_BLIT_COPYORDER_TL2BR = 0x0100, /* copy order overrides */ + PVR2D_BLIT_COPYORDER_BR2TL = 0x0200, + PVR2D_BLIT_COPYORDER_TR2BL = 0x0400, + PVR2D_BLIT_COPYORDER_BL2TR = 0x0800, + PVR2D_BLIT_COLKEY_SOURCE = 0x1000, /* Key colour is on the source surface */ + PVR2D_BLIT_COLKEY_DEST = 0x2000 /* Key colour is on the destination surface */ + +} PVR2DBLITFLAGS; + +/* standard alpha-blending functions, AlphaBlendingFunc field of PVR2DBLTINFO */ +typedef enum +{ + PVR2D_ALPHA_OP_SRC_DSTINV = 1, /* source alpha : Cdst = Csrc*Asrc + Cdst*(1-Asrc) */ + PVR2D_ALPHA_OP_SRCP_DSTINV = 2 /* premultiplied source alpha : Cdst = Csrc + Cdst*(1-Asrc) */ +} PVR2D_ALPHABLENDFUNC; + +/* blend ops for fully specified alpha */ +typedef enum +{ + PVR2D_BLEND_OP_ZERO = 0, + PVR2D_BLEND_OP_ONE = 1, + PVR2D_BLEND_OP_SRC = 2, + PVR2D_BLEND_OP_DST = 3, + PVR2D_BLEND_OP_GLOBAL = 4, + PVR2D_BLEND_OP_SRC_PLUS_GLOBAL = 5, + PVR2D_BLEND_OP_DST_PLUS_GLOBAL = 6 +}PVR2D_BLEND_OP; + + +typedef void* PVR2D_HANDLE; + + +/* Fully specified alpha blend : pAlpha field of PVR2DBLTINFO structure */ +/* a fully specified Alpha Blend operation is defined as */ +/* DST (ALPHA) = (ALPHA_1 * SRC (ALPHA)) + (ALPHA_3 * DST (ALPHA)) */ +/* DST (RGB) = (ALPHA_2 * SRC (RGB)) + (ALPHA_4 * DST (RGB)) */ +/* if the pre-multiplication stage is enabled then the equations become the following: */ +/* PRE_MUL = ((SRC(A)) * (Global Alpha Value)) */ +/* DST (ALPHA) = (ALPHA_1 * SRC (ALPHA)) + (PRE_MUL * DST (ALPHA)) */ +/* DST (RGB) = (ALPHA_2 * SRC (RGB)) + (PRE_MUL * DST (RGB)) */ +/* if the transparent source alpha stage is enabled then a source alpha of zero forces the */ +/* source to be transparent for that pixel regardless of the blend equation being used. */ +typedef struct _PVR2D_ALPHABLT +{ + PVR2D_BLEND_OP eAlpha1; + PVR2D_BOOL bAlpha1Invert; + PVR2D_BLEND_OP eAlpha2; + PVR2D_BOOL bAlpha2Invert; + PVR2D_BLEND_OP eAlpha3; + PVR2D_BOOL bAlpha3Invert; + PVR2D_BLEND_OP eAlpha4; + PVR2D_BOOL bAlpha4Invert; + PVR2D_BOOL bPremulAlpha; /* enable pre-multiplication stage */ + PVR2D_BOOL bTransAlpha; /* enable transparent source alpha stage */ + PVR2D_BOOL bUpdateAlphaLookup; /* enable and update the 1555-Lookup alpha table */ + unsigned char uAlphaLookup0; /* 8 bit alpha when A=0 in a 1555-Lookup surface */ + unsigned char uAlphaLookup1; /* 8 bit alpha when A=1 in a 1555-Lookup surface */ + unsigned char uGlobalRGB; /* Global Alpha Value for RGB, 0=transparent 255=opaque */ + unsigned char uGlobalA; /* Global Alpha Value for Alpha */ + +} PVR2D_ALPHABLT, *PPVR2D_ALPHABLT; + + +/* surface memory info structure */ +typedef struct _PVR2DMEMINFO +{ + void *pBase; + unsigned long ui32MemSize; + unsigned long ui32DevAddr; + unsigned long ulFlags; + void *hPrivateData; + void *hPrivateMapData; + +}PVR2DMEMINFO, *PPVR2DMEMINFO; + + +#define PVR2D_MAX_DEVICE_NAME 20 + +typedef struct _PVR2DDEVICEINFO +{ + unsigned long ulDevID; + char szDeviceName[PVR2D_MAX_DEVICE_NAME]; +}PVR2DDEVICEINFO; + + +typedef struct _PVR2DISPLAYINFO +{ + unsigned long ulMaxFlipChains; + unsigned long ulMaxBuffersInChain; + PVR2DFORMAT eFormat; + unsigned long ulWidth; + unsigned long ulHeight; + long lStride; + unsigned long ulMinFlipInterval; + unsigned long ulMaxFlipInterval; + +}PVR2DDISPLAYINFO; + + +typedef struct _PVR2DBLTINFO +{ + unsigned long CopyCode; /* rop code */ + unsigned long Colour; /* fill colour */ + unsigned long ColourKey; /* colour key */ + unsigned char GlobalAlphaValue; /* global alpha blending */ + unsigned char AlphaBlendingFunc; /* per-pixel alpha-blending function */ + + PVR2DBLITFLAGS BlitFlags; /* additional blit control information */ + + PVR2DMEMINFO *pDstMemInfo; /* destination memory */ + unsigned long DstOffset; /* byte offset from start of allocation to destination surface pixel 0,0 */ + long DstStride; /* signed stride, the number of bytes from pixel 0,0 to 0,1 */ + long DstX, DstY; /* pixel offset from start of dest surface to start of blt rectangle */ + long DSizeX,DSizeY; /* blt size */ + PVR2DFORMAT DstFormat; /* dest format */ + unsigned long DstSurfWidth; /* size of dest surface in pixels */ + unsigned long DstSurfHeight; /* size of dest surface in pixels */ + + PVR2DMEMINFO *pSrcMemInfo; /* source mem, (source fields are also used for patterns) */ + unsigned long SrcOffset; /* byte offset from start of allocation to src/pat surface pixel 0,0 */ + long SrcStride; /* signed stride, the number of bytes from pixel 0,0 to 0,1 */ + long SrcX, SrcY; /* pixel offset from start of surface to start of source rectangle */ + /* for patterns this is the start offset within the pattern */ + long SizeX,SizeY; /* source rectangle size or pattern size in pixels */ + PVR2DFORMAT SrcFormat; /* source/pattern format */ + PVR2DMEMINFO *pPalMemInfo; /* source/pattern palette memory containing argb8888 colour table */ + unsigned long PalOffset; /* byte offset from start of allocation to start of palette */ + unsigned long SrcSurfWidth; /* size of source surface in pixels */ + unsigned long SrcSurfHeight; /* size of source surface in pixels */ + + PVR2DMEMINFO *pMaskMemInfo; /* mask memory, 1bpp format implied */ + unsigned long MaskOffset; /* byte offset from start of allocation to mask surface pixel 0,0 */ + long MaskStride; /* signed stride, the number of bytes from pixel 0,0 to 0,1 */ + long MaskX, MaskY; /* mask rect top left (mask size = blt size) */ + unsigned long MaskSurfWidth; /* size of mask surface in pixels */ + unsigned long MaskSurfHeight; /* size of mask surface in pixels */ + + PPVR2D_ALPHABLT pAlpha; /* fully specified alpha blend */ + +}PVR2DBLTINFO, *PPVR2DBLTINFO; + +typedef struct _PVR2DRECT +{ + long left, top; + long right, bottom; +} PVR2DRECT; + +typedef struct +{ + PVR2DMEMINFO *pSurfMemInfo; /* surface memory */ + unsigned long SurfOffset; /* byte offset from start of allocation to destination surface pixel 0,0 */ + long Stride; /* signed stride */ + PVR2DFORMAT Format; + unsigned long SurfWidth; /* surface size in pixels */ + unsigned long SurfHeight; + +} PVR2D_SURFACE, *PPVR2D_SURFACE; + +typedef struct +{ + unsigned long *pUseCode; /* USSE code */ + unsigned long UseCodeSize; /* usse code size in bytes */ + +} PVR2D_USECODE, *PPVR2D_USECODE; + +typedef struct +{ + PVR2D_SURFACE sDst; /* destination surface */ + PVR2D_SURFACE sSrc; /* source surface */ + PVR2DRECT rcDest; /* destination rectangle */ + PVR2DRECT rcSource; /* source rectangle */ + PVR2D_HANDLE hUseCode; /* custom USE code (NULL implies source copy) */ + unsigned long UseParams[2]; /* per-blt params for use code */ + +} PVR2D_3DBLT, *PPVR2D_3DBLT; + + +#define MAKE_COPY_BLIT(src,soff,dest,doff,sx,sy,dx,dy,sz) + +typedef void* PVR2DCONTEXTHANDLE; +typedef void* PVR2DFLIPCHAINHANDLE; + + +// CopyCode field of PVR2DBLTINFO structure: +// the CopyCode field of the PVR2DBLTINFO structure should contain a rop3 or rop4 code. +// a rop3 is an 8 bit code that describes a blt with three inputs : source dest and pattern +// rop4 is a 16 bit code that describes a blt with four inputs : source dest pattern and mask +// common rop3 codes are defined below +// a colour fill blt is processed in the pattern channel as a constant colour with a rop code of 0xF0 +// PVR2D_BLIT_PAT_SURFACE_ENABLE defines whether the pattern channel is a surface or a fill colour. +// a rop4 is defined by two rop3 codes, and the 1 bit-per-pixel mask surface defines which is used. +// a common rop4 is 0xAAF0 which is the mask copy blt used for text glyphs. +// CopyCode is taken to be a rop4 when pMaskMemInfo is non zero, otherwise it is assumed to be a rop3 +// use the PVR2DMASKROP4 macro below to construct a rop4 from two rop3's +// rop3a is the rop used when mask pixel = 1, and rop3b when mask = 0 +#define PVR2DROP4(rop3b, rop3a) ((rop3b<<8)|rop3a) + +/* common rop codes */ +#define PVR2DROPclear 0x00 /* 0 (whiteness) */ +#define PVR2DROPset 0xFF /* 1 (blackness) */ +#define PVR2DROPnoop 0xAA /* dst (used for masked blts) */ + +/* source and dest rop codes */ +#define PVR2DROPand 0x88 /* src AND dst */ +#define PVR2DROPandReverse 0x44 /* src AND NOT dst */ +#define PVR2DROPcopy 0xCC /* src (used for source copy and alpha blts) */ +#define PVR2DROPandInverted 0x22 /* NOT src AND dst */ +#define PVR2DROPxor 0x66 /* src XOR dst */ +#define PVR2DROPor 0xEE /* src OR dst */ +#define PVR2DROPnor 0x11 /* NOT src AND NOT dst */ +#define PVR2DROPequiv 0x99 /* NOT src XOR dst */ +#define PVR2DROPinvert 0x55 /* NOT dst */ +#define PVR2DROPorReverse 0xDD /* src OR NOT dst */ +#define PVR2DROPcopyInverted 0x33 /* NOT src */ +#define PVR2DROPorInverted 0xBB /* NOT src OR dst */ +#define PVR2DROPnand 0x77 /* NOT src OR NOT dst */ + +/* pattern rop codes */ +#define PVR2DPATROPand 0xA0 /* pat AND dst */ +#define PVR2DPATROPandReverse 0x50 /* pat AND NOT dst */ +#define PVR2DPATROPcopy 0xF0 /* pat (used for solid color fills and pattern blts) */ +#define PVR2DPATROPandInverted 0x0A /* NOT pat AND dst */ +#define PVR2DPATROPxor 0x5A /* pat XOR dst */ +#define PVR2DPATROPor 0xFA /* pat OR dst */ +#define PVR2DPATROPnor 0x05 /* NOT pat AND NOT dst */ +#define PVR2DPATROPequiv 0xA5 /* NOT pat XOR dst */ +#define PVR2DPATROPinvert 0x55 /* NOT dst */ +#define PVR2DPATROPorReverse 0xF5 /* pat OR NOT dst */ +#define PVR2DPATROPcopyInverted 0x0F /* NOT pat */ +#define PVR2DPATROPorInverted 0xAF /* NOT pat OR dst */ +#define PVR2DPATROPnand 0x5F /* NOT pat OR NOT dst */ + +/* common rop4 codes */ +#define PVR2DROP4MaskedCopy PVR2DROP4(PVR2DROPnoop,PVR2DROPcopy) /* masked source copy blt (used for rounded window corners etc) */ +#define PVR2DROP4MaskedFill PVR2DROP4(PVR2DROPnoop,PVR2DPATROPcopy) /* masked colour fill blt (used for text) */ + +/* Legacy support */ +#define PVR2DROP3_PATMASK PVR2DPATROPcopy +#define PVR2DROP3_SRCMASK PVR2DROPcopy + +/* pixmap memory alignment */ +#define PVR2D_ALIGNMENT_4 4 /* DWORD alignment */ +#define PVR2D_ALIGNMENT_ANY 0 /* no alignment */ +#define PVR2D_ALIGNMENT_PALETTE 16 /* 16 byte alignment is required for palettes */ + +/* Heap number for PVR2DGetFrameBuffer */ +#define PVR2D_FB_PRIMARY_SURFACE 0 + +#define PVR2D_PRESENT_PROPERTY_SRCSTRIDE (1 << 0) +#define PVR2D_PRESENT_PROPERTY_DSTSIZE (1 << 1) +#define PVR2D_PRESENT_PROPERTY_DSTPOS (1 << 2) +#define PVR2D_PRESENT_PROPERTY_CLIPRECTS (1 << 3) +#define PVR2D_PRESENT_PROPERTY_INTERVAL (1 << 4) + + +#define PVR2D_CREATE_FLIPCHAIN_SHARED (1 << 0) +#define PVR2D_CREATE_FLIPCHAIN_QUERY (1 << 1) + +/* Functions that the library exports */ + +PVR2D_IMPORT +int PVR2DEnumerateDevices(PVR2DDEVICEINFO *pDevInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DCreateDeviceContext(unsigned long ulDevID, + PVR2DCONTEXTHANDLE* phContext, + unsigned long ulFlags); + +PVR2D_IMPORT +PVR2DERROR PVR2DDestroyDeviceContext(PVR2DCONTEXTHANDLE hContext); + +PVR2D_IMPORT +PVR2DERROR PVR2DGetDeviceInfo(PVR2DCONTEXTHANDLE hContext, + PVR2DDISPLAYINFO *pDisplayInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DGetScreenMode(PVR2DCONTEXTHANDLE hContext, + PVR2DFORMAT *pFormat, + long *plWidth, + long *plHeight, + long *plStride, + int *piRefreshRate); + +PVR2D_IMPORT +PVR2DERROR PVR2DGetFrameBuffer(PVR2DCONTEXTHANDLE hContext, + int nHeap, + PVR2DMEMINFO **ppsMemInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DMemAlloc(PVR2DCONTEXTHANDLE hContext, + unsigned long ulBytes, + unsigned long ulAlign, + unsigned long ulFlags, + PVR2DMEMINFO **ppsMemInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DMemWrap(PVR2DCONTEXTHANDLE hContext, + void *pMem, + unsigned long ulFlags, + unsigned long ulBytes, + unsigned long alPageAddress[], + PVR2DMEMINFO **ppsMemInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DMemMap(PVR2DCONTEXTHANDLE hContext, + unsigned long ulFlags, + void *hPrivateMapData, + PVR2DMEMINFO **ppsDstMem); + +PVR2D_IMPORT +PVR2DERROR PVR2DMemFree(PVR2DCONTEXTHANDLE hContext, + PVR2DMEMINFO *psMemInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DBlt(PVR2DCONTEXTHANDLE hContext, + PVR2DBLTINFO *pBltInfo); + +PVR2D_IMPORT +PVR2DERROR PVR2DBltClipped(PVR2DCONTEXTHANDLE hContext, + PVR2DBLTINFO *pBltInfo, + unsigned long ulNumClipRects, + PVR2DRECT *pClipRects); + +PVR2D_IMPORT +PVR2DERROR PVR2DQueryBlitsComplete(PVR2DCONTEXTHANDLE hContext, + PVR2DMEMINFO *pMemInfo, + unsigned int uiWaitForComplete); + +PVR2D_IMPORT +PVR2DERROR PVR2DSetPresentBltProperties(PVR2DCONTEXTHANDLE hContext, + unsigned long ulPropertyMask, + long lSrcStride, + unsigned long ulDstWidth, + unsigned long ulDstHeight, + long lDstXPos, + long lDstYPos, + unsigned long ulNumClipRects, + PVR2DRECT *pClipRects, + unsigned long ulSwapInterval); + +PVR2D_IMPORT +PVR2DERROR PVR2DPresentBlt(PVR2DCONTEXTHANDLE hContext, + PVR2DMEMINFO *pMemInfo, + long lRenderID); + +PVR2D_IMPORT +PVR2DERROR PVR2DCreateFlipChain(PVR2DCONTEXTHANDLE hContext, + unsigned long ulFlags, + unsigned long ulNumBuffers, + unsigned long ulWidth, + unsigned long ulHeight, + PVR2DFORMAT eFormat, + long *plStride, + unsigned long *pulFlipChainID, + PVR2DFLIPCHAINHANDLE *phFlipChain); + +PVR2D_IMPORT +PVR2DERROR PVR2DDestroyFlipChain(PVR2DCONTEXTHANDLE hContext, + PVR2DFLIPCHAINHANDLE hFlipChain); + +PVR2D_IMPORT +PVR2DERROR PVR2DGetFlipChainBuffers(PVR2DCONTEXTHANDLE hContext, + PVR2DFLIPCHAINHANDLE hFlipChain, + unsigned long *pulNumBuffers, + PVR2DMEMINFO *psMemInfo[]); + +PVR2D_IMPORT +PVR2DERROR PVR2DSetPresentFlipProperties(PVR2DCONTEXTHANDLE hContext, + PVR2DFLIPCHAINHANDLE hFlipChain, + unsigned long ulPropertyMask, + long lDstXPos, + long lDstYPos, + unsigned long ulNumClipRects, + PVR2DRECT *pClipRects, + unsigned long ulSwapInterval); + +PVR2D_IMPORT +PVR2DERROR PVR2DPresentFlip(PVR2DCONTEXTHANDLE hContext, + PVR2DFLIPCHAINHANDLE hFlipChain, + PVR2DMEMINFO *psMemInfo, + long lRenderID); + +PVR2D_IMPORT +PVR2DERROR PVR2DGetAPIRev(long *lRevMajor, long *lRevMinor); + +PVR2D_IMPORT +PVR2DERROR PVR2DLoadUseCode (const PVR2DCONTEXTHANDLE hContext, const unsigned char *pUseCode, + const unsigned long UseCodeSize, PVR2D_HANDLE *pUseCodeHandle); +PVR2D_IMPORT +PVR2DERROR PVR2DFreeUseCode (const PVR2DCONTEXTHANDLE hContext, const PVR2D_HANDLE hUseCodeHandle); + +PVR2D_IMPORT +PVR2DERROR PVR2DBlt3D (const PVR2DCONTEXTHANDLE hContext, const PPVR2D_3DBLT pBlt3D); + +#ifdef __cplusplus +} +#endif + +#endif /* _PVR2D_H_ */ + +/****************************************************************************** + End of file (pvr2d.h) +******************************************************************************/ diff --git a/src/3rdparty/powervr/wsegl.h b/src/3rdparty/powervr/wsegl.h new file mode 100644 index 0000000..0490607 --- /dev/null +++ b/src/3rdparty/powervr/wsegl.h @@ -0,0 +1,240 @@ +/****************************************************************************** + Name : wsegl.h + Copyright : Copyright (c) Imagination Technologies Limited. + This specification is protected by copyright laws and contains + material proprietary to Imagination Technologies Limited. + You may use and distribute this specification free of charge for implementing + the functionality therein, without altering or removing any trademark, copyright, + or other notice from the specification. + Platform : ANSI +*****************************************************************************/ + + +#if !defined(__WSEGL_H__) +#define __WSEGL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +// WSEGL Platform-specific definitions +*/ +#define WSEGL_EXPORT +#define WSEGL_IMPORT + +/* +// WSEGL API Version Number +*/ + +#define WSEGL_VERSION 1 +#define WSEGL_DEFAULT_DISPLAY 0 +#define WSEGL_DEFAULT_NATIVE_ENGINE 0 + +#define WSEGL_FALSE 0 +#define WSEGL_TRUE 1 +#define WSEGL_NULL 0 + +#define WSEGL_UNREFERENCED_PARAMETER(param) (param) = (param) + +/* +// WSEGL handles +*/ +typedef void *WSEGLDisplayHandle; +typedef void *WSEGLDrawableHandle; + +/* +// Display capability type +*/ +typedef enum WSEGLCapsType_TAG +{ + WSEGL_NO_CAPS = 0, + WSEGL_CAP_MIN_SWAP_INTERVAL = 1, /* System default value = 1 */ + WSEGL_CAP_MAX_SWAP_INTERVAL = 2, /* System default value = 1 */ + WSEGL_CAP_WINDOWS_USE_HW_SYNC = 3, /* System default value = 0 (FALSE) */ + WSEGL_CAP_PIXMAPS_USE_HW_SYNC = 4, /* System default value = 0 (FALSE) */ + +} WSEGLCapsType; + +/* +// Display capability +*/ +typedef struct WSEGLCaps_TAG +{ + WSEGLCapsType eCapsType; + unsigned long ui32CapsValue; + +} WSEGLCaps; + +/* +// Drawable type +*/ +#define WSEGL_NO_DRAWABLE 0x0 +#define WSEGL_DRAWABLE_WINDOW 0x1 +#define WSEGL_DRAWABLE_PIXMAP 0x2 + + +/* +// Pixel format of display/drawable +*/ +typedef enum WSEGLPixelFormat_TAG +{ + WSEGL_PIXELFORMAT_565 = 0, + WSEGL_PIXELFORMAT_4444 = 1, + WSEGL_PIXELFORMAT_8888 = 2, + WSEGL_PIXELFORMAT_1555 = 3 + +} WSEGLPixelFormat; + +/* +// Transparent of display/drawable +*/ +typedef enum WSEGLTransparentType_TAG +{ + WSEGL_OPAQUE = 0, + WSEGL_COLOR_KEY = 1, + +} WSEGLTransparentType; + +/* +// Display/drawable configuration +*/ +typedef struct WSEGLConfig_TAG +{ + /* + // Type of drawables this configuration applies to - + // OR'd values of drawable types. + */ + unsigned long ui32DrawableType; + + /* Pixel format */ + WSEGLPixelFormat ePixelFormat; + + /* Native Renderable - set to WSEGL_TRUE if native renderable */ + unsigned long ulNativeRenderable; + + /* FrameBuffer Level Parameter */ + unsigned long ulFrameBufferLevel; + + /* Native Visual ID */ + unsigned long ulNativeVisualID; + + /* Native Visual */ + void *hNativeVisual; + + /* Transparent Type */ + WSEGLTransparentType eTransparentType; + + /* Transparent Color - only used if transparent type is COLOR_KEY */ + unsigned long ulTransparentColor; /* packed as 0x00RRGGBB */ + + +} WSEGLConfig; + +/* +// WSEGL errors +*/ +typedef enum WSEGLError_TAG +{ + WSEGL_SUCCESS = 0, + WSEGL_CANNOT_INITIALISE = 1, + WSEGL_BAD_NATIVE_DISPLAY = 2, + WSEGL_BAD_NATIVE_WINDOW = 3, + WSEGL_BAD_NATIVE_PIXMAP = 4, + WSEGL_BAD_NATIVE_ENGINE = 5, + WSEGL_BAD_DRAWABLE = 6, + WSEGL_BAD_CONFIG = 7, + WSEGL_OUT_OF_MEMORY = 8 + +} WSEGLError; + +/* +// Drawable orientation (in degrees anti-clockwise) +*/ +typedef enum WSEGLRotationAngle_TAG +{ + WSEGL_ROTATE_0 = 0, + WSEGL_ROTATE_90 = 1, + WSEGL_ROTATE_180 = 2, + WSEGL_ROTATE_270 = 3 + +} WSEGLRotationAngle; + +/* +// Drawable information required by OpenGL-ES driver +*/ +typedef struct WSEGLDrawableParams_TAG +{ + /* Width in pixels of the drawable */ + unsigned long ui32Width; + + /* Height in pixels of the drawable */ + unsigned long ui32Height; + + /* Stride in pixels of the drawable */ + unsigned long ui32Stride; + + /* Pixel format of the drawable */ + WSEGLPixelFormat ePixelFormat; + + /* User space cpu virtual address of the drawable */ + void *pvLinearAddress; + + /* HW address of the drawable */ + unsigned long ui32HWAddress; + + /* Private data for the drawable */ + void *hPrivateData; + +} WSEGLDrawableParams; + + +/* +// Table of function pointers that is returned by WSEGL_GetFunctionTablePointer() +// +// The first entry in the table is the version number of the wsegl.h header file that +// the module has been written against, and should therefore be set to WSEGL_VERSION +*/ +typedef struct WSEGL_FunctionTable_TAG +{ + unsigned long ui32WSEGLVersion; + + WSEGLError (*pfnWSEGL_IsDisplayValid)(NativeDisplayType); + + WSEGLError (*pfnWSEGL_InitialiseDisplay)(NativeDisplayType, WSEGLDisplayHandle *, const WSEGLCaps **, WSEGLConfig **); + + WSEGLError (*pfnWSEGL_CloseDisplay)(WSEGLDisplayHandle); + + WSEGLError (*pfnWSEGL_CreateWindowDrawable)(WSEGLDisplayHandle, WSEGLConfig *, WSEGLDrawableHandle *, NativeWindowType, WSEGLRotationAngle *); + + WSEGLError (*pfnWSEGL_CreatePixmapDrawable)(WSEGLDisplayHandle, WSEGLConfig *, WSEGLDrawableHandle *, NativePixmapType, WSEGLRotationAngle *); + + WSEGLError (*pfnWSEGL_DeleteDrawable)(WSEGLDrawableHandle); + + WSEGLError (*pfnWSEGL_SwapDrawable)(WSEGLDrawableHandle, unsigned long); + + WSEGLError (*pfnWSEGL_SwapControlInterval)(WSEGLDrawableHandle, unsigned long); + + WSEGLError (*pfnWSEGL_WaitNative)(WSEGLDrawableHandle, unsigned long); + + WSEGLError (*pfnWSEGL_CopyFromDrawable)(WSEGLDrawableHandle, NativePixmapType); + + WSEGLError (*pfnWSEGL_CopyFromPBuffer)(void *, unsigned long, unsigned long, unsigned long, WSEGLPixelFormat, NativePixmapType); + + WSEGLError (*pfnWSEGL_GetDrawableParameters)(WSEGLDrawableHandle, WSEGLDrawableParams *, WSEGLDrawableParams *); + + +} WSEGL_FunctionTable; + + +WSEGL_IMPORT const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __WSEGL_H__ */ + +/****************************************************************************** + End of file (wsegl.h) +******************************************************************************/ diff --git a/src/corelib/concurrent/qfutureinterface.h b/src/corelib/concurrent/qfutureinterface.h index 85d03c9..345bebe 100644 --- a/src/corelib/concurrent/qfutureinterface.h +++ b/src/corelib/concurrent/qfutureinterface.h @@ -165,6 +165,8 @@ public: QFutureInterface &operator=(const QFutureInterface &other) { + if (referenceCountIsOne()) + resultStore().clear(); QFutureInterfaceBase::operator=(other); return *this; } diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 3c015da..f63d29e 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -67,7 +67,8 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 1 Note that you cannot use QTextStream::atEnd(), which returns true when you - have reached the end of the data stream, with stdin. + have reached the end of the data stream, with stdin because as long as the + application is running, stdin has no end. Besides using QTextStream's constructors, you can also set the device or string QTextStream operates on by calling setDevice() or diff --git a/src/gui/dialogs/qabstractprintdialog.cpp b/src/gui/dialogs/qabstractprintdialog.cpp index 0dc16c9..5ed8852 100644 --- a/src/gui/dialogs/qabstractprintdialog.cpp +++ b/src/gui/dialogs/qabstractprintdialog.cpp @@ -400,7 +400,7 @@ void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter) QAbstractPrintDialog::setEnabledOptions() and QAbstractPrintDialog::addEnabledOption() have no effect. - In Qt 4.4, it was possible to use the satic functions to show a sheet on + In Qt 4.4, it was possible to use the static functions to show a sheet on Mac OS X. This is no longer supported in Qt 4.5. If you want this functionality, use QPrintDialog::open(). diff --git a/src/gui/embedded/qscreentransformed_qws.cpp b/src/gui/embedded/qscreentransformed_qws.cpp index 46ac1d1..e22ea1f 100644 --- a/src/gui/embedded/qscreentransformed_qws.cpp +++ b/src/gui/embedded/qscreentransformed_qws.cpp @@ -400,7 +400,19 @@ void QTransformedScreen::blit(const QImage &image, const QPoint &topLeft, #endif #if defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15) || defined(QT_QWS_DEPTH_12) case 16: +#if defined QT_QWS_ROTATE_BGR + if (pixelType() == BGRPixel && image.depth() == 16) { + SET_BLIT_FUNC(qbgr565, quint16, trans, func); + break; + } //fall-through here!!! +#endif case 15: +#if defined QT_QWS_ROTATE_BGR + if (pixelType() == BGRPixel && image.format() == QImage::Format_RGB555) { + SET_BLIT_FUNC(qbgr555, qrgb555, trans, func); + break; + } //fall-through here!!! +#endif case 12: if (image.depth() == 16) SET_BLIT_FUNC(quint16, quint16, trans, func); diff --git a/src/gui/embedded/qscreenvfb_qws.cpp b/src/gui/embedded/qscreenvfb_qws.cpp index abbe73b..accfe1f 100644 --- a/src/gui/embedded/qscreenvfb_qws.cpp +++ b/src/gui/embedded/qscreenvfb_qws.cpp @@ -310,6 +310,9 @@ bool QVFbScreen::connect(const QString &displaySpec) connected = this; + if (qgetenv("QT_QVFB_BGR").toInt()) + pixeltype = BGRPixel; + return true; } diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp index dffebf2..fdcd193 100644 --- a/src/gui/embedded/qwindowsystem_qws.cpp +++ b/src/gui/embedded/qwindowsystem_qws.cpp @@ -4044,7 +4044,7 @@ void QWSServer::setDesktopBackground(const QImage &img) */ void QWSServer::setDesktopBackground(const QColor &c) { - setDesktopBackground(QBrush(c)); + setBackground(QBrush(c)); } #endif //QT3_SUPPORT diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 65d1e0a..7be7df5 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1961,7 +1961,7 @@ void QGraphicsItem::setOpacity(qreal opacity) itemChange(ItemOpacityHasChanged, newOpacity); // Update. - d_ptr->fullUpdateHelper(); + d_ptr->fullUpdateHelper(/*childrenOnly=*/false, /*maybeDirtyClipPath=*/false, /*ignoreOpacity=*/true); } /*! @@ -3276,10 +3276,16 @@ bool QGraphicsItem::contains(const QPointF &point) const } /*! - Returns true if this item collides with \a other; otherwise returns false. - The ways items collide is determined by \a mode. The default value for \a - mode is Qt::IntersectsItemShape; \a other collides with this item if it - either intersects, contains, or is contained by this item's shape. + + Returns true if this item collides with \a other; otherwise + returns false. + + The \a mode is applied to \a other, and the resulting shape or + bounding rectangle is then compared to this item's shape. The + default value for \a mode is Qt::IntersectsItemShape; \a other + collides with this item if it either intersects, contains, or is + contained by this item's shape (see Qt::ItemSelectionMode for + details). The default implementation is based on shape intersection, and it calls shape() on both items. Because the complexity of arbitrary shape-shape @@ -3334,6 +3340,11 @@ bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelecti Qt::IntersectsItemShape; \a path collides with this item if it either intersects, contains, or is contained by this item's shape. + Note that this function checks whether the item's shape or + bounding rectangle (depending on \a mode) is contained within \a + path, and not whether \a path is contained within the items shape + or bounding rectangle. + \sa collidesWithItem(), contains(), shape() */ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const @@ -3374,11 +3385,12 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection /*! Returns a list of all items that collide with this item. - The way collisions are detected is determined by \a mode. The default - value for \a mode is Qt::IntersectsItemShape; All items whose shape - intersects or is contained by this item's shape are returned. + The way collisions are detected is determined by applying \a mode + to items that are compared to this item, i.e., each item's shape + or bounding rectangle is checked against this item's shape. The + default value for \a mode is Qt::IntersectsItemShape. - \sa QGraphicsScene::collidingItems(), collidesWithItem() + \sa collidesWithItem() */ QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const { @@ -3662,9 +3674,8 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) \internal Returns true if we can discard an update request; otherwise false. */ -bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, - bool ignoreVisibleBit, - bool ignoreDirtyBit) const +bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit, + bool ignoreDirtyBit, bool ignoreOpacity) const { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. @@ -3673,7 +3684,7 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, || !scene || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect) || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) - || (childrenCombineOpacity() && isFullyTransparent()); + || (!ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } /*! @@ -3703,11 +3714,10 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may Propagates updates to \a item and all its children. */ -void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath) +void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath, bool ignoreOpacity) { - if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, - /*ignoreVisibleBit=*/false, - /*ignoreDirtyBit=*/true)) { + if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/false, + /*ignoreDirtyBit=*/true, ignoreOpacity)) { return; } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 940e566..2936cf1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -166,11 +166,10 @@ public: void setPosHelper(const QPointF &pos); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); - bool discardUpdateRequest(bool ignoreClipping = false, - bool ignoreVisibleBit = false, - bool ignoreDirtyBit = false) const; + bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, + bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); - void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false); + void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false, bool ignoreOpacity = false); void updateEffectiveOpacity(); void resolveEffectiveOpacity(qreal effectiveParentOpacity); void resolveDepth(int parentDepth); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 644e843..2876016 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1081,8 +1081,12 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedReg QList<QGraphicsItem *> itemList(scene->items()); int i = 0; while (i < itemList.size()) { + const QGraphicsItem *item = itemList.at(i); // But we only want to include items that are visible - if (!itemList.at(i)->isVisible()) + // The following check is basically the same as item->d_ptr->isInvisible(), except + // that we don't check whether the item clips children to shape or propagates its + // opacity (we loop through all items, so those checks are wrong in this context). + if (!item->isVisible() || item->d_ptr->isClippedAway() || item->d_ptr->isFullyTransparent()) itemList.removeAt(i); else ++i; diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 5de39d9..7f36be9 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1337,6 +1337,7 @@ QByteArray QImageReader::imageFormat(QIODevice *device) \row \o TIFF \o Tagged Image File Format \row \o XBM \o X11 Bitmap \row \o XPM \o X11 Pixmap + \row \o SVG \o Scalable Vector Graphics \endtable Reading and writing SVG files is supported through Qt's diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index a5a194f..3e00cd0 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1997,14 +1997,15 @@ bool QListViewPrivate::doItemsLayout(int delta) int first = batchStartRow(); int last = qMin(first + delta - 1, max); - if (max < 0 || last < first) - return true; // nothing to do - if (first == 0) { layoutChildren(); // make sure the viewport has the right size prepareItemsLayout(); } + if (max < 0 || last < first) { + return true; // nothing to do + } + QListViewLayoutInfo info; info.bounds = layoutBounds; info.grid = gridSize(); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 07b3865..f1ab90f 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2429,10 +2429,12 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam widget = (QETWidget*)qApp->focusWidget(); HWND focus = ::GetFocus(); //if there is a current widget and the new widget belongs to the same toplevel window + //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP) //then we clear the focus on the widget //in case the new widget belongs to a different widget hierarchy, clearing the focus //will be handled because the active window will change - if (widget && ::IsChild(widget->window()->internalWinId(), focus)) { + const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded; + if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) { widget->clearFocus(); result = true; } else { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index d7ca2f4..25356da 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3168,43 +3168,48 @@ int QApplication::x11ProcessEvent(XEvent* event) #ifdef ALIEN_DEBUG //qDebug() << "QApplication::x11ProcessEvent:" << event->type; #endif + Time time = 0, userTime = 0; switch (event->type) { case ButtonPress: pressed_window = event->xbutton.window; - X11->userTime = event->xbutton.time; + userTime = event->xbutton.time; // fallthrough intended case ButtonRelease: - X11->time = event->xbutton.time; + time = event->xbutton.time; break; case MotionNotify: - X11->time = event->xmotion.time; + time = event->xmotion.time; break; case XKeyPress: - X11->userTime = event->xkey.time; + userTime = event->xkey.time; // fallthrough intended case XKeyRelease: - X11->time = event->xkey.time; + time = event->xkey.time; break; case PropertyNotify: - X11->time = event->xproperty.time; + time = event->xproperty.time; break; case EnterNotify: case LeaveNotify: - X11->time = event->xcrossing.time; + time = event->xcrossing.time; break; case SelectionClear: - X11->time = event->xselectionclear.time; + time = event->xselectionclear.time; break; default: - break; - } #ifndef QT_NO_XFIXES - if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { - XFixesSelectionNotifyEvent *req = - reinterpret_cast<XFixesSelectionNotifyEvent *>(event); - X11->time = req->selection_timestamp; - } + if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { + XFixesSelectionNotifyEvent *req = + reinterpret_cast<XFixesSelectionNotifyEvent *>(event); + time = req->selection_timestamp; + } #endif + break; + } + if (time > X11->time) + X11->time = time; + if (userTime > X11->userTime) + X11->userTime = userTime; QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window); diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index dad15d9..9a24645 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -183,21 +183,24 @@ static void cleanupCocoaApplicationDelegate() { Q_UNUSED(sender); // The reflection delegate gets precedence - NSApplicationTerminateReply reply = NSTerminateCancel; if (reflectionDelegate && [reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) { return [reflectionDelegate applicationShouldTerminate:sender]; } if (qtPrivate->canQuit()) { - reply = NSTerminateNow; if (!startedQuit) { startedQuit = true; qAppInstance()->quit(); startedQuit = false; } } - return reply; + + // Prevent Cocoa from terminating the application, since this simply + // exits the program whithout allowing QApplication::exec() to return. + // The call to QApplication::quit() above will instead quit the + // application from the Qt side. + return NSTerminateCancel; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 60ac062..1cbc960 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -199,6 +199,7 @@ extern "C" { composingText = new QString(); composing = false; sendKeyEvents = true; + currentCustomTypes = 0; [self setHidden:YES]; return self; } @@ -213,10 +214,16 @@ extern "C" { object:self]; } --(void)registerDragTypes:(bool)accept +-(void)registerDragTypes { QMacCocoaAutoReleasePool pool; - if (accept) { + // Calling registerForDraggedTypes is slow, so only do it once for each widget + // or when the custom types change. + const QStringList& customTypes = qEnabledDraggedTypes(); + if (currentCustomTypes == 0 || *currentCustomTypes != customTypes) { + if (currentCustomTypes == 0) + currentCustomTypes = new QStringList(); + *currentCustomTypes = customTypes; const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName"; NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType, NSFilenamesPboardType, NSStringPboardType, @@ -228,13 +235,10 @@ extern "C" { NSFilesPromisePboardType, NSInkTextPboardType, NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil]; // Add custom types supported by the application. - const QStringList& customTypes = qEnabledDraggedTypes(); for (int i = 0; i < customTypes.size(); i++) { [supportedTypes addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(customTypes[i]))]; } [self registerForDraggedTypes:supportedTypes]; - } else { - [self unregisterDraggedTypes]; } } @@ -283,6 +287,8 @@ extern "C" { - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender { + if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false) + return NSDragOperationNone; [self addDropData:sender]; QMimeData *mimeData = dropData; if (QDragManager::self()->source()) @@ -416,6 +422,8 @@ extern "C" { { delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; + delete currentCustomTypes; + [self unregisterDraggedTypes]; [super dealloc]; } diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index ec1281e..1d4e3e4 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -84,6 +84,7 @@ Q_GUI_EXPORT int composingLength; bool sendKeyEvents; QString *composingText; + QStringList *currentCustomTypes; } - (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; - (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; @@ -92,7 +93,7 @@ Q_GUI_EXPORT - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender; - (void)draggingExited:(id < NSDraggingInfo >)sender; - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender; -- (void)registerDragTypes:(bool)accept; +- (void)registerDragTypes; - (void)removeDropData; - (void)addDropData:(id <NSDraggingInfo>)sender; - (void)setSupportedActions:(NSDragOperation)actions; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index f000292..9165836 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -826,13 +826,28 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev QWidget *qwidget = [theView qt_qwidget]; QWidget *widgetToGetMouse = qwidget; QWidget *popup = qAppInstance()->activePopupWidget(); - if (popup && popup != qwidget->window()) - widgetToGetMouse = popup; NSView *tmpView = theView; - if (widgetToGetMouse != qwidget) { - tmpView = qt_mac_nativeview_for(widgetToGetMouse); + + if (popup && popup != qwidget->window()) { + widgetToGetMouse = popup; + tmpView = qt_mac_nativeview_for(popup); windowPoint = [[tmpView window] convertScreenToBase:globalPoint]; + + QPoint qWindowPoint(windowPoint.x, windowPoint.y); + if (widgetToGetMouse->rect().contains(qWindowPoint)) { + // Keeping the mouse pressed on a combobox button will make + // the popup pop in front of the mouse. But all mouse events + // will be sendt to the button. Since we want mouse events + // to be sendt to widgets inside the popup, we search for the + // widget in front of the mouse: + tmpView = [tmpView hitTest:windowPoint]; + if (!tmpView) + return false; + widgetToGetMouse = + [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; + } } + NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; QPoint qlocalPoint(localPoint.x, localPoint.y); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index dd95053..cbf9585 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4810,7 +4810,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, Q_ASSERT(engine); QPaintEnginePrivate *enginePriv = engine->d_func(); Q_ASSERT(enginePriv); - QPaintDevice *target = painter->worldMatrixEnabled() ? engine->paintDevice() : painter->device(); + QPaintDevice *target = engine->paintDevice(); Q_ASSERT(target); // Render via a pixmap when dealing with non-opaque painters or printers. diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 9da0b6b..1896b97 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4491,8 +4491,8 @@ void QWidgetPrivate::registerDropSite(bool on) SetControlDragTrackingEnabled(qt_mac_nativeview_for(q), on); #else NSView *view = qt_mac_nativeview_for(q); - if ([view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { - [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) registerDragTypes:on]; + if (on && [view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { + [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) registerDragTypes]; } #endif } diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 16dd617..8f4a2bf 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -44,8 +44,6 @@ QT_BEGIN_NAMESPACE -static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; - struct SourceOnlyAlpha { inline uchar alpha(uchar src) const { return src; } @@ -140,14 +138,11 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha { template <typename SRC, typename T> void qt_scale_image_16bit(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, - const QRectF &target, + const QRectF &targetRect, const QRectF &srcRect, const QRect &clip, T blender) { - const QRectF targetRect = target.translated(aliasedCoordinateDelta, - aliasedCoordinateDelta); - qreal sx = targetRect.width() / (qreal) srcRect.width(); qreal sy = targetRect.height() / (qreal) srcRect.height(); @@ -617,14 +612,11 @@ struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha { template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, - const QRectF &target, + const QRectF &targetRect, const QRectF &srcRect, const QRect &clip, T blender) { - const QRectF targetRect = target.translated(aliasedCoordinateDelta, - aliasedCoordinateDelta); - qreal sx = targetRect.width() / (qreal) srcRect.width(); qreal sy = targetRect.height() / (qreal) srcRect.height(); diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 4058143..471f544 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -528,6 +528,26 @@ void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ qt_memrotate270_template(src, w, h, sstride, dest, dstride); \ } +#define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype) \ +void qt_memrotate90(const srctype *src, int w, int h, int sstride, \ + desttype *dest, int dstride) \ +{ \ + qt_memrotate90_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \ +} \ +void qt_memrotate180(const srctype *src, int w, int h, int sstride, \ + desttype *dest, int dstride) \ +{ \ + qt_memrotate180_template(src, w, h, sstride, dest, dstride); \ +} \ +void qt_memrotate270(const srctype *src, int w, int h, int sstride, \ + desttype *dest, int dstride) \ +{ \ + qt_memrotate270_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \ +} + + + + QT_IMPL_MEMROTATE(quint32, quint32) QT_IMPL_MEMROTATE(quint32, quint16) QT_IMPL_MEMROTATE(quint16, quint32) @@ -539,6 +559,14 @@ QT_IMPL_MEMROTATE(quint32, quint8) QT_IMPL_MEMROTATE(quint16, quint8) QT_IMPL_MEMROTATE(qrgb444, quint8) QT_IMPL_MEMROTATE(quint8, quint8) + +#if defined(QT_QWS_ROTATE_BGR) +QT_IMPL_SIMPLE_MEMROTATE(quint16, qbgr565) +QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr565) +QT_IMPL_SIMPLE_MEMROTATE(qrgb555, qbgr555) +QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr555) +#endif + #ifdef QT_QWS_DEPTH_GENERIC QT_IMPL_MEMROTATE(quint32, qrgb_generic16) QT_IMPL_MEMROTATE(quint16, qrgb_generic16) diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h index c1eb93e..87cfb1a 100644 --- a/src/gui/painting/qmemrotate_p.h +++ b/src/gui/painting/qmemrotate_p.h @@ -92,6 +92,14 @@ QT_DECL_MEMROTATE(quint32, quint8); QT_DECL_MEMROTATE(quint16, quint8); QT_DECL_MEMROTATE(qrgb444, quint8); QT_DECL_MEMROTATE(quint8, quint8); + +#ifdef QT_QWS_ROTATE_BGR +QT_DECL_MEMROTATE(quint16, qbgr565); +QT_DECL_MEMROTATE(quint32, qbgr565); +QT_DECL_MEMROTATE(qrgb555, qbgr555); +QT_DECL_MEMROTATE(quint32, qbgr555); +#endif + #ifdef QT_QWS_DEPTH_GENERIC QT_DECL_MEMROTATE(quint32, qrgb_generic16); QT_DECL_MEMROTATE(quint16, qrgb_generic16); diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index 0644a02..5889388 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -996,15 +996,14 @@ void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, co } else if (differentSize) { #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - CGImageRef img = (CGImageRef)pm.macCGHandle(); + QCFType<CGImageRef> img = pm.toMacCGImageRef(); image = CGImageCreateWithImageInRect(img, CGRectMake(qRound(sr.x()), qRound(sr.y()), qRound(sr.width()), qRound(sr.height()))); - CGImageRelease(img); } else #endif { const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height()); const QMacPixmapData *pmData = static_cast<const QMacPixmapData*>(pm.data); - quint32 *pantherData = pmData->pixels + (sy * pm.width() + sx); + quint32 *pantherData = pmData->pixels + sy * (pmData->bytesPerRow / 4) + sx; QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, pantherData, sw*sh*pmData->bytesPerRow, 0); image = CGImageCreate(sw, sh, 8, 32, pmData->bytesPerRow, macGenericColorSpace(), diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9b13352..3428faf 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1026,7 +1026,7 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, int alpha, const QRect &sr) { - if (!clip.isValid()) + if (alpha == 0 || !clip.isValid()) return; Q_ASSERT(img.depth() >= 8); @@ -2577,7 +2577,11 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe QRasterPaintEngineState *s = state(); const bool aa = s->flags.antialiased || s->flags.bilinear; if (!aa && sr.size() == QSize(1, 1)) { - fillRect(r, QColor::fromRgba(img.pixel(sr.x(), sr.y()))); + // as fillRect will apply the aliased coordinate delta we need to + // subtract it here as we don't use it for image drawing + const QRectF targetRect = r.translated(-aliasedCoordinateDelta, + -aliasedCoordinateDelta); + fillRect(targetRect, QColor::fromRgba(img.pixel(sr.x(), sr.y()))); return; } @@ -2668,7 +2672,13 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe QRectF rr = r; rr.translate(s->matrix.dx(), s->matrix.dy()); - fillRect_normalized(toRect_normalized(rr), &d->image_filler, d); + + const int x1 = qRound(rr.x()); + const int y1 = qRound(rr.y()); + const int x2 = qRound(rr.right()); + const int y2 = qRound(rr.bottom()); + + fillRect_normalized(QRect(x1, y1, x2-x1, y2-y1), &d->image_filler, d); } } @@ -5151,7 +5161,11 @@ void QSpanData::adjustSpanMethods() void QSpanData::setupMatrix(const QTransform &matrix, int bilin) { - QTransform inv = matrix.inverted(); + QTransform delta; + // make sure we round off correctly in qdrawhelper.cpp + delta.translate(1.0 / 65536, 1.0 / 65536); + + QTransform inv = (delta * matrix).inverted(); m11 = inv.m11(); m12 = inv.m12(); m13 = inv.m13(); diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 4b2fbca..9cc9683 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1543,6 +1543,8 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p QX11PaintEnginePrivate::GCMode gcMode, QPaintEngine::PolygonDrawMode mode) { + Q_Q(QX11PaintEngine); + int clippedCount = 0; qt_float_point *clippedPoints = 0; @@ -1617,7 +1619,29 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p } else #endif if (fill.style() != Qt::NoBrush) { - if (clippedCount > 0) { + if (clippedCount > 200000) { + QPolygon poly; + for (int i = 0; i < clippedCount; ++i) + poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y)); + + const QRect bounds = poly.boundingRect(); + const QRect aligned = bounds + & QRect(QPoint(), QSize(pdev->width(), pdev->height())); + + QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied); + img.fill(0); + + QPainter painter(&img); + painter.translate(-aligned.x(), -aligned.y()); + painter.setPen(Qt::NoPen); + painter.setBrush(fill); + if (gcMode == BrushGC) + painter.setBrushOrigin(q->painter()->brushOrigin()); + painter.drawPolygon(poly); + painter.end(); + + q->drawImage(aligned, img, img.rect(), Qt::AutoColor); + } else if (clippedCount > 0) { QVarLengthArray<XPoint> xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { xpoints[i].x = qFloor(clippedPoints[i].x); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b158392..413d25c 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5142,6 +5142,11 @@ void QPainter::drawConvexPolygon(const QPointF *points, int pointCount) d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode); } +static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m) +{ + return m.inverted().map(QPointF(m.map(p).toPoint())); +} + /*! \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source) @@ -5210,11 +5215,12 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))) { save(); - // If there is no scaling or transformation involved we have to make sure we use the + // If there is no rotation involved we have to make sure we use the // antialiased and not the aliased coordinate system by rounding the coordinates. - if (d->state->matrix.type() <= QTransform::TxTranslate) { - x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx(); - y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy(); + if (d->state->matrix.type() <= QTransform::TxScale) { + const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix); + x = p.x(); + y = p.y(); } translate(x, y); setBackgroundMode(Qt::TransparentMode); @@ -5324,16 +5330,21 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) || ((sw != w || sh != h) && !d->engine->hasFeature(QPaintEngine::PixmapTransform))) { save(); - // If there is no scaling or transformation involved we have to make sure we use the + // If there is no rotation involved we have to make sure we use the // antialiased and not the aliased coordinate system by rounding the coordinates. + if (d->state->matrix.type() <= QTransform::TxScale) { + const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix); + x = p.x(); + y = p.y(); + } + if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) { - x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx(); - y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy(); sx = qRound(sx); sy = qRound(sy); sw = qRound(sw); sh = qRound(sh); } + translate(x, y); scale(w / sw, h / sh); setBackgroundMode(Qt::TransparentMode); @@ -5483,11 +5494,12 @@ void QPainter::drawImage(const QPointF &p, const QImage &image) || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))) { save(); - // If there is no scaling or transformation involved we have to make sure we use the + // If there is no rotation involved we have to make sure we use the // antialiased and not the aliased coordinate system by rounding the coordinates. - if (d->state->matrix.type() <= QTransform::TxTranslate) { - x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx(); - y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy(); + if (d->state->matrix.type() <= QTransform::TxScale) { + const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix); + x = p.x(); + y = p.y(); } translate(x, y); setBackgroundMode(Qt::TransparentMode); @@ -5586,11 +5598,15 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))) { save(); - // If there is no scaling or transformation involved we have to make sure we use the + // If there is no rotation involved we have to make sure we use the // antialiased and not the aliased coordinate system by rounding the coordinates. + if (d->state->matrix.type() <= QTransform::TxScale) { + const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix); + x = p.x(); + y = p.y(); + } + if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) { - x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx(); - y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy(); sx = qRound(sx); sy = qRound(sy); sw = qRound(sw); @@ -6333,17 +6349,18 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo setBrush(QBrush(d->state->pen.color(), pixmap)); setPen(Qt::NoPen); - // If there is no scaling or transformation involved we have to make sure we use the + // If there is no rotation involved we have to make sure we use the // antialiased and not the aliased coordinate system by rounding the coordinates. - if (d->state->matrix.type() <= QTransform::TxTranslate) { - qreal x = qRound(r.x() + d->state->matrix.dx()) - d->state->matrix.dx(); - qreal y = qRound(r.y() + d->state->matrix.dy()) - d->state->matrix.dy(); - qreal w = qRound(r.width()); - qreal h = qRound(r.height()); - sx = qRound(sx); - sy = qRound(sy); + if (d->state->matrix.type() <= QTransform::TxScale) { + const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix); + + if (d->state->matrix.type() <= QTransform::TxTranslate) { + sx = qRound(sx); + sy = qRound(sy); + } + setBrushOrigin(QPointF(r.x()-sx, r.y()-sy)); - drawRect(QRectF(x, y, w, h)); + drawRect(QRectF(p, r.size())); } else { setBrushOrigin(QPointF(r.x()-sx, r.y()-sy)); drawRect(r); diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index e1535f8..1d12bed 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1780,46 +1780,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, case CE_TabBarTab: if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { drawControl(CE_TabBarTabShape, tab, p, widget); - - QStyleOptionTabV3 tabV3(*tab); - QRect labelRect = tabV3.rect; - QSize &left= tabV3.leftButtonSize; - QSize &right = tabV3.rightButtonSize; - const int spacing = 6 + 2; - - // left widget - if (!left.isEmpty()) { - if (tabV3.shape == QTabBar::RoundedEast || tabV3.shape == QTabBar::TriangularEast ) - labelRect.setTop(labelRect.top() + spacing + left.height()); - else if (tabV3.shape == QTabBar::RoundedWest|| tabV3.shape == QTabBar::TriangularWest) - labelRect.setBottom(labelRect.bottom() - spacing - left.height()); - else - labelRect.setLeft(labelRect.left() + spacing + left.width()); - } - - // right widget - if (!right.isEmpty()) { - if (tabV3.shape == QTabBar::RoundedEast || tabV3.shape == QTabBar::TriangularEast ) - labelRect.setBottom(labelRect.bottom() - spacing - right.height()); - else if (tabV3.shape == QTabBar::RoundedWest|| tabV3.shape == QTabBar::TriangularWest) - labelRect.setTop(labelRect.top() + spacing + right.height()); - else - labelRect.setRight(labelRect.right() - spacing - right.width()); - } - - tabV3.rect = visualRect(opt->direction, opt->rect, labelRect); - drawControl(CE_TabBarTabLabel, &tabV3, p, widget); - if (tabV3.state & State_HasFocus) { - const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth); - int x1, x2; - x1 = tab->rect.left(); - x2 = tab->rect.right() - 1; - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*tab); - fropt.rect.setRect(x1 + 1 + OFFSET, tab->rect.y() + OFFSET, - x2 - x1 - 2*OFFSET, tab->rect.height() - 2*OFFSET); - drawPrimitive(PE_FrameFocusRect, &fropt, p, widget); - } + drawControl(CE_TabBarTabLabel, tab, p, widget); } break; case CE_TabBarTabShape: @@ -2023,8 +1984,12 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, (tabV2.state & State_Selected) ? QIcon::On : QIcon::Off); - int offset = 6; + int offset = 4; int left = opt->rect.left(); + if (tabV2.leftButtonSize.isEmpty()) + offset += 2; + else + left += tabV2.leftButtonSize.width() + (6 + 2) + 2; QRect iconRect = QRect(left + offset, tr.center().y() - tabIcon.height() / 2, tabIconSize.width(), tabIconSize.height()); if (!verticalTabs) @@ -2035,6 +2000,20 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); if (verticalTabs) p->restore(); + + if (tabV2.state & State_HasFocus) { + const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth); + + int x1, x2; + x1 = tabV2.rect.left(); + x2 = tabV2.rect.right() - 1; + + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*tab); + fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET, + x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET); + drawPrimitive(PE_FrameFocusRect, &fropt, p, widget); + } } break; #endif // QT_NO_TABBAR @@ -2884,6 +2863,12 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, tr.setRight(tr.right() - horizontalShift); } + // left widget + if (!tabV2.leftButtonSize.isEmpty()) { + tr.setLeft(tr.left() + 6 + 2 + + (verticalTabs ? tabV2.leftButtonSize.height() : tabV2.leftButtonSize.width())); + } + // icon if (!tabV2.icon.isNull()) { QSize iconSize = tabV2.iconSize; @@ -2905,6 +2890,12 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, tr.setLeft(tr.left() + tabIconSize.width() + offset + 2); } + // right widget + if (!tabV2.rightButtonSize.isEmpty()) { + tr.setRight(tr.right() - 6 - 2 - + (verticalTabs ? tabV2.rightButtonSize.height() : tabV2.rightButtonSize.width())); + } + if (!verticalTabs) tr = visualRect(opt->direction, opt->rect, tr); r = tr; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 47fe5c2..d7a9c23 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -624,6 +624,45 @@ QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int /* margin */, const Q return rgbMask; } +QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) +{ + glyph_metrics_t gm = boundingBox(glyph); + int glyph_x = qFloor(gm.x.toReal()); + int glyph_y = qFloor(gm.y.toReal()); + int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x; + int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y; + + if (glyph_width <= 0 || glyph_height <= 0) + return QImage(); + QFixedPoint pt; + pt.x = 0; + pt.y = -glyph_y; // the baseline + QPainterPath path; + QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied); + im.fill(Qt::transparent); + QPainter p(&im); + p.setRenderHint(QPainter::Antialiasing); + addGlyphsToPath(&glyph, &pt, 1, &path, 0); + p.setPen(Qt::NoPen); + p.setBrush(Qt::black); + p.drawPath(path); + p.end(); + + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); + QVector<QRgb> colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgba(0, 0, 0, i); + indexed.setColorTable(colors); + + for (int y=0; y<im.height(); ++y) { + uchar *dst = (uchar *) indexed.scanLine(y); + uint *src = (uint *) im.scanLine(y); + for (int x=0; x<im.width(); ++x) + dst[x] = qAlpha(src[x]); + } + + return indexed; +} void QFontEngine::removeGlyphFromCache(glyph_t) { diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index cb0b436..de03a3c 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1788,9 +1788,11 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g) GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono; - Glyph *glyph = loadGlyph(g, glyph_format); - if (!glyph) - return QImage(); + Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format); + if (!glyph) { + unlockFace(); + return QFontEngine::alphaMapForGlyph(g); + } const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 8f6b92a..92efb6c 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -178,7 +178,7 @@ public: * Create a qimage with the alpha values for the glyph. * Returns an image indexed_8 with index values ranging from 0=fully transparant to 255=opaque */ - virtual QImage alphaMapForGlyph(glyph_t) = 0; + virtual QImage alphaMapForGlyph(glyph_t); virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t); diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index c327b9f..48963bb 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1074,7 +1074,10 @@ QTextCursor::QTextCursor(const QTextCursor &cursor) } /*! - Makes a copy of \a cursor and assigns it to this QTextCursor. + Makes a copy of \a cursor and assigns it to this QTextCursor. Note + that QTextCursor is an \l{Implicitly Shared Classes}{implicitly + shared} class. + */ QTextCursor &QTextCursor::operator=(const QTextCursor &cursor) { diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index e84b324..873f846 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -287,7 +287,7 @@ QTextCodec *Qt::codecForHtml(const QByteArray &ba) that inform connected editor widgets about the state of the undo/redo system. - \sa QTextCursor QTextEdit \link richtext.html Rich Text Processing\endlink + \sa QTextCursor, QTextEdit, \link richtext.html Rich Text Processing\endlink , {Text Object Example} */ /*! diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 3f4c8e5..71b68e0 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE objects, you will also need to reimplement QTextDocument::createObject() which acts as a factory method for creating text objects. - \sa QTextDocument + \sa QTextDocument, {Text Object Example} */ /*! diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 1afb28a..502c1e9 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -480,9 +480,6 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar) oldMenuBar->hide(); oldMenuBar->deleteLater(); } -#ifdef Q_WS_WINCE - if (menuBar && menuBar->size().height() > 0) -#endif d->layout->setMenuBar(menuBar); } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index a51ed2d..14efd23 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -629,7 +629,7 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) if (viewport->updatesEnabled() && viewport->isVisible()) { int dy = 0; - if (doc->findBlockByLineNumber(control->topBlock).isValid()) { + if (doc->findBlockByNumber(control->topBlock).isValid()) { dy = (int)(-q->blockBoundingGeometry(block).y()) + verticalOffset() - verticalOffset(blockNumber, lineNumber); } diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index ce1ac09..0b4ce9d 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1084,7 +1084,7 @@ void QTabBar::setTabData(int index, const QVariant & data) } /*! - Returns the datad of the tab at position \a index, or a null + Returns the data of the tab at position \a index, or a null variant if \a index is out of range. */ QVariant QTabBar::tabData(int index) const @@ -2223,6 +2223,7 @@ void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget) d->tabList[index].rightWidget = widget; } d->layoutTabs(); + d->refresh(); update(); } diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index aaa5075..82c9344 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -1197,6 +1197,13 @@ bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieLis || isParentDomain(defaultDomain, domain))) { continue; // not accepted } + + // reject if domain is like ".com" + // (i.e., reject if domain does not contain embedded dots, see RFC 2109 section 4.3.2) + // this is just a rudimentary check and does not cover all cases + if (domain.lastIndexOf(QLatin1Char('.')) == 0) + continue; // not accepted + } QList<QNetworkCookie>::Iterator it = d->allCookies.begin(), diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 14a04f1..d42370d 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -193,7 +193,11 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) } else { QString templateName = d->tmpCacheFileName(); cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data); - cacheItem->file->open(); + if (!cacheItem->file->open()) { + qWarning() << "QNetworkDiskCache::prepare() unable to open temporary file"; + delete cacheItem; + return 0; + } cacheItem->writeHeader(cacheItem->file); device = cacheItem->file; } @@ -231,7 +235,7 @@ void QNetworkDiskCachePrivate::storeItem(QCacheItem *cacheItem) if (QFile::exists(fileName)) { if (!QFile::remove(fileName)) { - qWarning() << "QNetworkDiskCache: could't remove the cache file " << fileName; + qWarning() << "QNetworkDiskCache: couldn't remove the cache file " << fileName; return; } } diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp index 505c662..7fec2df 100644 --- a/src/network/ssl/qsslcipher.cpp +++ b/src/network/ssl/qsslcipher.cpp @@ -64,9 +64,9 @@ #ifndef QT_NO_DEBUG_STREAM #include <QtCore/qdebug.h> +#endif QT_BEGIN_NAMESPACE -#endif /*! Constructs an empty QSslCipher object. diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 77ff9fb..aee351d 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -5067,9 +5067,8 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte // fall back to drawing a polygon if the scale factor is large, or // we use a gradient pen - if (ti.fontEngine->fontDef.pixelSize >= 64 - || (d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern - && d->pen_brush_style <= Qt::ConicalGradientPattern)) { + if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern + && d->pen_brush_style <= Qt::ConicalGradientPattern)) { QPaintEngine::drawTextItem(p, textItem); return; } diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 67f5d61..5c60b2f 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -6,6 +6,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers # These defines might be necessary if your DirectFB driver doesn't # support all of the DirectFB API. # +#DEFINES += QT_DIRECTFB_IMAGECACHE #DEFINES += QT_NO_DIRECTFB_WM #DEFINES += QT_NO_DIRECTFB_LAYER #DEFINES += QT_NO_DIRECTFB_PALETTE @@ -22,7 +23,7 @@ target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target HEADERS = qdirectfbscreen.h \ - qdirectfbsurface.h \ + qdirectfbwindowsurface.h \ qdirectfbpaintengine.h \ qdirectfbpaintdevice.h \ qdirectfbpixmap.h \ @@ -31,7 +32,7 @@ HEADERS = qdirectfbscreen.h \ SOURCES = qdirectfbscreen.cpp \ qdirectfbscreenplugin.cpp \ - qdirectfbsurface.cpp \ + qdirectfbwindowsurface.cpp \ qdirectfbpaintengine.cpp \ qdirectfbpaintdevice.cpp \ qdirectfbpixmap.cpp \ @@ -40,4 +41,4 @@ SOURCES = qdirectfbscreen.cpp \ QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB LIBS += $$QT_LIBS_DIRECTFB - +DEFINES += $$QT_DEFINES_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 924090c..72e0ce5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -56,15 +56,20 @@ IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const } -void QDirectFBPaintDevice::lockDirectFB() +void QDirectFBPaintDevice::lockDirectFB(uint flags) { - if (lockedImage) - return; // Already locked - - if (uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, DSLF_WRITE, &bpl)) { - const QSize s = size(); - lockedImage = new QImage(mem, s.width(), s.height(), bpl, - QDirectFBScreen::getImageFormat(dfbSurface)); + if (!(lock & flags)) { + if (lock) + unlockDirectFB(); + if ((mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl))) { + const QSize s = size(); + lockedImage = new QImage(mem, s.width(), s.height(), bpl, + QDirectFBScreen::getImageFormat(dfbSurface)); + lock = flags; + Q_ASSERT(mem); + } else { + lock = 0; + } } } @@ -77,15 +82,19 @@ void QDirectFBPaintDevice::unlockDirectFB() dfbSurface->Unlock(dfbSurface); delete lockedImage; lockedImage = 0; + mem = 0; + lock = 0; } -void* QDirectFBPaintDevice::memory() const +void *QDirectFBPaintDevice::memory() const { - QDirectFBPaintDevice* that = const_cast<QDirectFBPaintDevice*>(this); - that->lockDirectFB(); - Q_ASSERT(that->lockedImage); - return that->lockedImage->bits(); + if (lock != (DSLF_READ|DSLF_WRITE)) { + QDirectFBPaintDevice *that = const_cast<QDirectFBPaintDevice*>(this); + that->lockDirectFB(DSLF_READ|DSLF_WRITE); + Q_ASSERT(that->lockedImage); + } + return mem; } @@ -101,7 +110,7 @@ int QDirectFBPaintDevice::bytesPerLine() const // Can only get the stride when we lock the surface Q_ASSERT(!lockedImage); QDirectFBPaintDevice* that = const_cast<QDirectFBPaintDevice*>(this); - that->lockDirectFB(); + that->lockDirectFB(DSLF_READ); Q_ASSERT(bpl != -1); } return bpl; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index a11064b..13f0a8f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -58,7 +58,7 @@ public: IDirectFBSurface *directFBSurface() const; - void lockDirectFB(); + void lockDirectFB(uint flags); void unlockDirectFB(); inline bool forceRasterPrimitives() const { return forceRaster; } @@ -69,6 +69,7 @@ public: int bytesPerLine() const; QSize size() const; int metric(QPaintDevice::PaintDeviceMetric metric) const; + uint lockFlags() const { return lock; } protected: // Shouldn't create QDirectFBPaintDevice by itself but only sub-class it: QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance()) @@ -76,7 +77,10 @@ protected: dfbSurface(0), lockedImage(0), screen(scr), - forceRaster(false) {} + forceRaster(false), + lock(0), + mem(0) + {} inline int dotsPerMeterX() const { @@ -92,6 +96,8 @@ protected: QDirectFBScreen *screen; int bpl; bool forceRaster; + uint lock; + uchar *mem; private: Q_DISABLE_COPY(QDirectFBPaintDevice) }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 14d2146..91a60e7 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -43,7 +43,7 @@ #ifndef QT_NO_DIRECTFB -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbscreen.h" #include "qdirectfbpixmap.h" #include <directfb.h> @@ -80,7 +80,7 @@ template <typename T> inline const T *ptr(const T &t) { return &t; } template <> inline const bool* ptr<bool>(const bool &) { return 0; } template <typename device, typename T1, typename T2, typename T3> static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, - bool matrixScale, bool matrixRotShear, bool simplePen, + int scale, bool matrixRotShear, bool simplePen, bool dfbHandledClip, bool forceRasterPrimitives, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, @@ -95,7 +95,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * dbg << dev << "of type" << dev->devType(); } - dbg << "matrixScale" << matrixScale + dbg << "scale" << scale << "matrixRotShear" << matrixRotShear << "simplePen" << simplePen << "dfbHandledClip" << dfbHandledClip @@ -123,7 +123,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ rasterFallbackWarn("Disabled raster engine operation", \ __FUNCTION__, state()->painter->device(), \ - d_func()->matrixScale, d_func()->matrixRotShear, \ + d_func()->scale, d_func()->matrixRotShear, \ d_func()->simplePen, d_func()->dfbCanHandleClip(), \ d_func()->forceRasterPrimitives, \ #one, one, #two, two, #three, three); \ @@ -138,7 +138,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ rasterFallbackWarn("Falling back to raster engine for", \ __FUNCTION__, state()->painter->device(), \ - d_func()->matrixScale, d_func()->matrixRotShear, \ + d_func()->scale, d_func()->matrixRotShear, \ d_func()->simplePen, d_func()->dfbCanHandleClip(), \ d_func()->forceRasterPrimitives, \ #one, one, #two, two, #three, three); @@ -156,129 +156,66 @@ static inline uint ALPHA_MUL(uint x, uint a) class SurfaceCache { public: - SurfaceCache(); - ~SurfaceCache(); + SurfaceCache() : surface(0), buffer(0), bufsize(0) {} + ~SurfaceCache() { clear(); } - inline IDirectFBSurface *getSurface(const uint *buffer, int size); - inline void clear(); -private: - IDirectFBSurface *surface; - uint *buffer; - int bufsize; -}; - -SurfaceCache::SurfaceCache() - : surface(0), buffer(0), bufsize(0) -{ -} + IDirectFBSurface *getSurface(const uint *buf, int size) + { + if (buffer == buf && bufsize == size) + return surface; -class CachedImage -{ -public: - CachedImage(const QImage &image); - ~CachedImage(); + clear(); - IDirectFBSurface *surface() { return s; } + const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size); + surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface); + if (!surface) + qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface"); -private: - IDirectFBSurface *s; -}; - -CachedImage::CachedImage(const QImage &image) - : s(0) -{ - IDirectFBSurface *tmpSurface = 0; - DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(image); - QDirectFBScreen* screen = QDirectFBScreen::instance(); + buffer = const_cast<uint*>(buf); + bufsize = size; - tmpSurface = screen->createDFBSurface(description, QDirectFBScreen::TrackSurface); - if (!tmpSurface) { - qWarning("CachedImage CreateSurface failed!"); - return; + return surface; } -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(tmpSurface, image); -#endif - - description.flags = DFBSurfaceDescriptionFlags(description.flags & ~DSDESC_PREALLOCATED); - - s = screen->createDFBSurface(description, QDirectFBScreen::TrackSurface); - if (!s) - qWarning("QDirectFBPaintEngine failed caching image"); - -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(s, image); -#endif - - if (s) { - s->SetBlittingFlags(s, DSBLIT_NOFX); - s->Blit(s, tmpSurface, 0, 0, 0); - s->ReleaseSource(s); + void clear() + { + if (surface && QDirectFBScreen::instance()) + QDirectFBScreen::instance()->releaseDFBSurface(surface); + surface = 0; + buffer = 0; + bufsize = 0; } - if (tmpSurface) - screen->releaseDFBSurface(tmpSurface); -} - -CachedImage::~CachedImage() -{ - if (s && QDirectFBScreen::instance()) - QDirectFBScreen::instance()->releaseDFBSurface(s); -} - -static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB - -IDirectFBSurface* SurfaceCache::getSurface(const uint *buf, int size) -{ - if (buffer == buf && bufsize == size) - return surface; - - clear(); - - const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size); - surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface); - if (!surface) - qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface"); - - buffer = const_cast<uint*>(buf); - bufsize = size; - - return surface; -} +private: + IDirectFBSurface *surface; + uint *buffer; + int bufsize; +}; -void SurfaceCache::clear() -{ - if (surface) - QDirectFBScreen::instance()->releaseDFBSurface(surface); - surface = 0; - buffer = 0; - bufsize = 0; -} -SurfaceCache::~SurfaceCache() +#ifdef QT_DIRECTFB_IMAGECACHE +#include <private/qimage_p.h> +struct CachedImage { - clear(); -} + IDirectFBSurface *surface; + ~CachedImage() + { + if (surface && QDirectFBScreen::instance()) { + QDirectFBScreen::instance()->releaseDFBSurface(surface); + } + } +}; +static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB +#endif class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate { public: + enum Scale { NoScale, Scaled, NegativeScale }; + QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p); ~QDirectFBPaintEnginePrivate(); - IDirectFBSurface *surface; - - QPen pen; - - bool antialiased; - bool forceRasterPrimitives; - - bool simplePen; - - bool matrixRotShear; - bool matrixScale; - void setTransform(const QTransform &m); void setPen(const QPen &pen); void setCompositionMode(QPainter::CompositionMode mode); @@ -304,24 +241,39 @@ public: void fillRects(const QRectF *rects, int count); void drawRects(const QRectF *rects, int count); - - void drawPixmap(const QRectF &dest, - const QPixmap &pixmap, const QRectF &src); void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap); - void drawImage(const QRectF &dest, const QImage &image, const QRectF &src); + void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src); inline void updateClip(); - inline void setClipDirty(); void systemStateChanged(); void begin(QPaintDevice *device); void end(); + static IDirectFBSurface *getSurface(const QImage &img, bool *release); + +#ifdef QT_DIRECTFB_IMAGECACHE + static inline int cacheCost(const QImage &img) { return img.width() * img.height() * img.depth() / 8; } +#endif + void prepareForBlit(bool alpha); +private: + IDirectFBSurface *surface; + + QPen pen; + + bool antialiased; + bool forceRasterPrimitives; + + bool simplePen; + + bool matrixRotShear; + Scale scale; + SurfaceCache *surfaceCache; QTransform transform; int lastLockedHeight; -private: + IDirectFB *fb; DFBSurfaceDescription fbDescription; int fbWidth; @@ -336,469 +288,12 @@ private: bool dfbHandledClip; bool ignoreSystemClip; QDirectFBPaintDevice *dfbDevice; + void *lockedMemory; QDirectFBPaintEngine *q; + friend class QDirectFBPaintEngine; }; -QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) - : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), - matrixRotShear(false), matrixScale(false), lastLockedHeight(-1), - fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), - blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), - dfbHandledClip(false), dfbDevice(0), q(p) -{ - fb = QDirectFBScreen::instance()->dfb(); - ignoreSystemClip = QDirectFBScreen::instance()->directFBFlags() & QDirectFBScreen::IgnoreSystemClip; - surfaceCache = new SurfaceCache; - static int cacheLimit = qgetenv("QT_DIRECTFB_IMAGECACHE").toInt(); - if (cacheLimit > 0) - imageCache.setMaxCost(cacheLimit * 1024); -} - -QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate() -{ - delete surfaceCache; -} - -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRect &rect) const -{ - // TODO: Check to see if DirectFB can handle the clip for the given rect - return dfbHandledClip; -} - -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRectF &rect) const -{ - // TODO: Check to see if DirectFB can handle the clip for the given rect - return dfbHandledClip; -} - -bool QDirectFBPaintEnginePrivate::dfbCanHandleClip() const -{ - return dfbHandledClip; -} - -bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const -{ - return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); -} - -void QDirectFBPaintEnginePrivate::setClipDirty() -{ - dirtyClip = true; -} - -void QDirectFBPaintEnginePrivate::lock() -{ - // We will potentially get a new pointer to the buffer after a - // lock so we need to call the base implementation of prepare so - // it updates its rasterBuffer to point to the new buffer address. - lastLockedHeight = dfbDevice->height(); - - Q_ASSERT(dfbDevice); - prepare(dfbDevice); -} - -void QDirectFBPaintEnginePrivate::unlock() -{ - Q_ASSERT(dfbDevice); - dfbDevice->unlockDirectFB(); -} - -void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) -{ - transform = m; - matrixRotShear = (transform.m12() != 0 || transform.m21() != 0); - matrixScale = (transform.m11() != 1 || transform.m22() != 1); -} - -void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) -{ - lastLockedHeight = -1; - if (device->devType() == QInternal::CustomRaster) - dfbDevice = static_cast<QDirectFBPaintDevice*>(device); - else if (device->devType() == QInternal::Pixmap) { - QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data); - dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData); - } - - if (dfbDevice) - surface = dfbDevice->directFBSurface(); - - if (!surface) { - qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", - device->devType()); - } - forceRasterPrimitives = dfbDevice->forceRasterPrimitives(); - - surface->GetSize(surface, &fbWidth, &fbHeight); - - setTransform(QTransform()); - antialiased = false; - opacity = 255; - setCompositionMode(q->state()->compositionMode()); - dirtyClip = true; - setPen(q->state()->pen); - setDFBColor(pen.color()); -} - -void QDirectFBPaintEnginePrivate::end() -{ - dfbDevice = 0; - surface->ReleaseSource(surface); - surface->SetClip(surface, NULL); - surface = 0; -} - -void QDirectFBPaintEnginePrivate::setPen(const QPen &p) -{ - pen = p; - simplePen = (pen.style() == Qt::NoPen) || - (pen.style() == Qt::SolidLine - && !antialiased - && (pen.brush().style() == Qt::SolidPattern) - && (pen.widthF() <= 1 && !matrixScale)); -} - -void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) -{ - blitFlagsFromCompositionMode = DSBLIT_NOFX; - drawFlagsFromCompositionMode = DSDRAW_NOFX; - - bool blend = true; - switch (mode) { - case QPainter::CompositionMode_SourceOver: - porterDuffRule = DSPD_SRC_OVER; - break; - case QPainter::CompositionMode_DestinationOver: - porterDuffRule = DSPD_DST_OVER; - break; - case QPainter::CompositionMode_Clear: - porterDuffRule = DSPD_CLEAR; - blend = false; - break; - case QPainter::CompositionMode_Source: - porterDuffRule = DSPD_SRC; - blend = false; - break; - case QPainter::CompositionMode_Destination: - porterDuffRule = DSPD_NONE; // ### need to double check this - blend = false; - return; - case QPainter::CompositionMode_SourceIn: - porterDuffRule = DSPD_SRC_IN; - break; - case QPainter::CompositionMode_DestinationIn: - porterDuffRule = DSPD_DST_IN; - break; - case QPainter::CompositionMode_SourceOut: - porterDuffRule = DSPD_SRC_OUT; - break; - case QPainter::CompositionMode_DestinationOut: - porterDuffRule = DSPD_DST_OUT; - break; - case QPainter::CompositionMode_Xor: - porterDuffRule = DSPD_XOR; - blitFlagsFromCompositionMode |= DSBLIT_XOR; - drawFlagsFromCompositionMode |= DSDRAW_XOR; - break; -// case QPainter::CompositionMode_Plus: // ??? -// porterDuffRule = DSPD_ADD; -// break; - default: - qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): " - "mode %d not implemented", mode); - return; - } - // intentially not comparing with current porterDuffRule. surface might have changed. - if (blend) { - blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL; - drawFlagsFromCompositionMode |= DSDRAW_BLEND; - } - if (opacity != 255) { - setOpacity(opacity); - } -} - -void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) -{ - opacity = op; - if (opacity == 255) { - blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA; - } else { - blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA; - } -} - -void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) -{ - const bool old = antialiased; - antialiased = bool(hints & QPainter::Antialiasing); - if (old != antialiased) { - setPen(q->state()->pen); - } -} - -void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) -{ - quint32 blittingFlags = blitFlagsFromCompositionMode; - if (alpha) { - surface->SetPorterDuff(surface, - (blittingFlags & DSBLIT_BLEND_COLORALPHA) - ? DSPD_NONE - : porterDuffRule); - } else { - blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetPorterDuff(surface, DSPD_NONE); - } - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); -} - -void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) -{ - Q_ASSERT(surface); - const quint8 alpha = (opacity == 255 ? - color.alpha() : ALPHA_MUL(color.alpha(), opacity)); - surface->SetColor(surface, - color.red(), color.green(), color.blue(), alpha); - quint32 drawingFlags = drawFlagsFromCompositionMode; - if (alpha == 255) { - drawingFlags &= ~DSDRAW_BLEND; - } - surface->SetPorterDuff(surface, DSPD_NONE); - // PorterDuff messes up alpha values for primitives - surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags)); -} - -void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) -{ - for (int i = 0; i < n; ++i) { - const QLine l = transform.map(lines[i]); - surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); - } -} - -void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) -{ - for (int i = 0; i < n; ++i) { - const QLine l = transform.map(lines[i]).toLine(); - surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); - } -} - -void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) -{ - Q_ASSERT(isSimpleBrush(q->state()->brush)); - setDFBColor(q->state()->brush.color()); - const QVector<QRect> rects = region.rects(); - const int n = rects.size(); - fillRects(rects.constData(), n); -} - -void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) -{ - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]); - surface->FillRectangle(surface, r.x(), r.y(), - r.width(), r.height()); - } -} - -void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) -{ - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]).toRect(); - surface->FillRectangle(surface, r.x(), r.y(), - r.width(), r.height()); - } -} - -void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) -{ - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]); - surface->DrawRectangle(surface, r.x(), r.y(), - r.width() + 1, r.height() + 1); - } -} - -void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) -{ - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]).toRect(); - surface->DrawRectangle(surface, r.x(), r.y(), - r.width() + 1, r.height() + 1); - } -} - -void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, - const QPixmap &pixmap, - const QRectF &src) -{ - prepareForBlit(pixmap.hasAlphaChannel()); - QPixmapData *data = pixmap.pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - IDirectFBSurface *s = dfbData->directFBSurface(); - const QRect sr = src.toRect(); - const QRect dr = transform.mapRect(dest).toRect(); - const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; - DFBResult result; - - if (dr.size() == sr.size()) { - result = surface->Blit(surface, s, &sRect, dr.x(), dr.y()); - } else { - const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() }; - result = surface->StretchBlit(surface, s, &sRect, &dRect); - } - if (result != DFB_OK) - DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); -} - -void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, - const QPixmap &pixmap) -{ - prepareForBlit(pixmap.hasAlphaChannel()); - QPixmapData *data = pixmap.pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - IDirectFBSurface *s = dfbData->directFBSurface(); - const QRect dr = transform.mapRect(dest).toRect(); - DFBResult result = DFB_OK; - - if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) { - result = surface->TileBlit(surface, s, 0, 0, 0); - } else if (!matrixScale) { - const int dx = pixmap.width(); - const int dy = pixmap.height(); - const DFBRectangle rect = { 0, 0, dx, dy }; - QVarLengthArray<DFBRectangle> rects; - QVarLengthArray<DFBPoint> points; - - for (int y = dr.y(); y <= dr.bottom(); y += dy) { - for (int x = dr.x(); x <= dr.right(); x += dx) { - rects.append(rect); - const DFBPoint point = { x, y }; - points.append(point); - } - } - result = surface->BatchBlit(surface, s, rects.constData(), - points.constData(), points.size()); - } else { - const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); - const int dx = sr.width(); - const int dy = sr.height(); - const DFBRectangle sRect = { 0, 0, dx, dy }; - - for (int y = dr.y(); y <= dr.bottom(); y += dy) { - for (int x = dr.x(); x <= dr.right(); x += dx) { - const DFBRectangle dRect = { x, y, dx, dy }; - result = surface->StretchBlit(surface, s, &sRect, &dRect); - if (result != DFB_OK) { - y = dr.bottom() + 1; - break; - } - } - } - } - - if (result != DFB_OK) - DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); -} - -void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, - const QImage &image, - const QRectF &src) -{ - Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN); - CachedImage *img = imageCache[image.cacheKey()]; - IDirectFBSurface *imgSurface = 0; - bool doRelease = false; - - if (img) { - imgSurface = img->surface(); - } else { - const int cost = image.width() * image.height() * image.depth() / 8; - if (cost <= imageCache.maxCost()) { - img = new CachedImage(image); - imgSurface = img->surface(); - if (imgSurface) { - imageCache.insert(image.cacheKey(), img, cost); - } else { - delete img; - img = 0; - } - } - - if (!imgSurface) { - DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(image); - imgSurface = QDirectFBScreen::instance()->createDFBSurface(description, - QDirectFBScreen::DontTrackSurface); - if (!imgSurface) { - qWarning("QDirectFBPaintEnginePrivate::drawImage"); - return; - } - -#ifndef QT_NO_DIRECTFB_PALETTE - QDirectFBScreen::setSurfaceColorTable(surface, image); -#endif - doRelease = (imgSurface != 0); - } - } - - const QRect sr = src.toRect(); - const QRect dr = transform.mapRect(dest).toRect(); - const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; - - prepareForBlit(image.hasAlphaChannel()); - if (dr.size() == sr.size()) { - surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y()); - } else { - const DFBRectangle dRect = { dr.x(), dr.y(), - dr.width(), dr.height() }; - surface->StretchBlit(surface, imgSurface, &sRect, &dRect); - } - if (doRelease) { - surface->ReleaseSource(surface); - imgSurface->Release(imgSurface); - } -} - -void QDirectFBPaintEnginePrivate::updateClip() -{ - if (!dirtyClip) - return; - - const QClipData *clipData = clip(); - if (!clipData || !clipData->enabled) { - surface->SetClip(surface, NULL); - dfbHandledClip = true; - } else if (clipData->hasRectClip) { - const DFBRegion r = { - clipData->clipRect.x(), - clipData->clipRect.y(), - clipData->clipRect.x() + clipData->clipRect.width(), - clipData->clipRect.y() + clipData->clipRect.height() - }; - surface->SetClip(surface, &r); - dfbHandledClip = true; - } else if (clipData->hasRegionClip && ignoreSystemClip && clipData->clipRegion == systemClip) { - dfbHandledClip = true; - } else { - dfbHandledClip = false; - } - - dirtyClip = false; -} - -void QDirectFBPaintEnginePrivate::systemStateChanged() -{ - setClipDirty(); - QRasterPaintEnginePrivate::systemStateChanged(); -} - QDirectFBPaintEngine::QDirectFBPaintEngine(QPaintDevice *device) : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device) { @@ -827,12 +322,10 @@ bool QDirectFBPaintEngine::end() return QRasterPaintEngine::end(); } - - void QDirectFBPaintEngine::clipEnabledChanged() { Q_D(QDirectFBPaintEngine); - d->setClipDirty(); + d->dirtyClip = true; QRasterPaintEngine::clipEnabledChanged(); } @@ -868,9 +361,9 @@ void QDirectFBPaintEngine::renderHintsChanged() void QDirectFBPaintEngine::transformChanged() { Q_D(QDirectFBPaintEngine); - const bool old = d->matrixScale; + const QDirectFBPaintEnginePrivate::Scale old = d->scale; d->setTransform(state()->transform()); - if (d->matrixScale != old) { + if (d->scale != old) { d->setPen(state()->pen); } QRasterPaintEngine::transformChanged(); @@ -880,7 +373,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s) { Q_D(QDirectFBPaintEngine); QRasterPaintEngine::setState(s); - d->setClipDirty(); + d->dirtyClip = true; d->setPen(state()->pen); d->setOpacity(quint8(state()->opacity * 255)); d->setCompositionMode(state()->compositionMode()); @@ -890,7 +383,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s) void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); - d->setClipDirty(); + d->dirtyClip = true; const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2)); if (bottom.y() >= d->lastLockedHeight) d->lock(); @@ -900,7 +393,7 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); - d->setClipDirty(); + d->dirtyClip = true; if (d->clip() && !d->clip()->hasRectClip && d->clip()->enabled) { const QPoint bottom = d->transform.map(QPoint(0, rect.bottom())); if (bottom.y() >= d->lastLockedHeight) @@ -1003,12 +496,36 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, Qt::ImageConversionFlags flags) { Q_D(QDirectFBPaintEngine); - Q_UNUSED(flags); // XXX + Q_UNUSED(flags); + + /* This is hard to read. The way it works is like this: + + - If you do not have support for preallocated surfaces and do not use an + image cache we always fall back to raster engine. + + - If it's rotated/sheared/mirrored (negative scale) or we can't + clip it we fall back to raster engine. + + - If we don't cache the image, but we do have support for + preallocated surfaces we fall back to the raster engine if the + image is in a format DirectFB can't handle. + + - If we do cache the image but don't have support for preallocated + images and the cost of caching the image (bytes used) is higher + than the max image cache size we fall back to raster engine. + */ -#ifndef QT_NO_DIRECTFB_PREALLOCATED d->updateClip(); - if (!d->dfbCanHandleClip(r) || d->matrixRotShear - || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) +#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE + if (d->matrixRotShear + || d->scale == QDirectFBPaintEnginePrivate::NegativeScale + || !d->dfbCanHandleClip(r) +#ifndef QT_DIRECTFB_IMAGECACHE + || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN +#elif defined QT_NO_DIRECTFB_PREALLOCATED + || QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost() +#endif + ) #endif { RASTERFALLBACK(DRAW_IMAGE, r, image.size(), sr); @@ -1016,10 +533,16 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, QRasterPaintEngine::drawImage(r, image, sr, flags); return; } - -#ifndef QT_NO_DIRECTFB_PREALLOCATED +#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE d->unlock(); - d->drawImage(r, image, sr); + bool release; + IDirectFBSurface *imgSurface = d->getSurface(image, &release); + d->prepareForBlit(QDirectFBScreen::hasAlpha(imgSurface)); + d->blit(r, imgSurface, sr); + if (release) { + imgSurface->ReleaseSource(imgSurface); + imgSurface->Release(imgSurface); + } #endif } @@ -1038,14 +561,20 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear + || d->scale == QDirectFBPaintEnginePrivate::NegativeScale) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); - const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(); + const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); QRasterPaintEngine::drawImage(r, *img, sr); } else { d->unlock(); - d->drawPixmap(r, pixmap, sr); + d->prepareForBlit(pixmap.hasAlphaChannel()); + QPixmapData *data = pixmap.pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); + IDirectFBSurface *s = dfbData->directFBSurface(); + d->blit(r, s, sr); } } @@ -1064,9 +593,10 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp); d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); - } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull() + || d->scale == QDirectFBPaintEnginePrivate::NegativeScale) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp); - const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(); + const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); @@ -1254,4 +784,457 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, d->surface->Blit(d->surface, src, &rect, x, y); } +#ifdef QT_DIRECTFB_IMAGECACHE +static void cachedImageCleanupHook(qint64 key) +{ + delete imageCache.take(key); +} +void QDirectFBPaintEngine::initImageCache(int size) +{ + Q_ASSERT(size >= 0); + imageCache.setMaxCost(size); + typedef void (*_qt_image_cleanup_hook_64)(qint64); + extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; + qt_image_cleanup_hook_64 = ::cachedImageCleanupHook; +} + +#endif // QT_DIRECTFB_IMAGECACHE + +// ---- QDirectFBPaintEnginePrivate ---- + + +QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) + : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), + matrixRotShear(false), scale(NoScale), lastLockedHeight(-1), + fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), + blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), + dfbHandledClip(false), dfbDevice(0), lockedMemory(0), q(p) +{ + fb = QDirectFBScreen::instance()->dfb(); + ignoreSystemClip = QDirectFBScreen::instance()->directFBFlags() & QDirectFBScreen::IgnoreSystemClip; + surfaceCache = new SurfaceCache; +} + +QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate() +{ + delete surfaceCache; +} + +bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRect &rect) const +{ + // TODO: Check to see if DirectFB can handle the clip for the given rect + return dfbHandledClip; +} + +bool QDirectFBPaintEnginePrivate::dfbCanHandleClip(const QRectF &rect) const +{ + // TODO: Check to see if DirectFB can handle the clip for the given rect + return dfbHandledClip; +} + +bool QDirectFBPaintEnginePrivate::dfbCanHandleClip() const +{ + return dfbHandledClip; +} + +bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const +{ + return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); +} + +void QDirectFBPaintEnginePrivate::lock() +{ + // We will potentially get a new pointer to the buffer after a + // lock so we need to call the base implementation of prepare so + // it updates its rasterBuffer to point to the new buffer address. + Q_ASSERT(dfbDevice); + if (dfbDevice->lockFlags() != (DSLF_WRITE|DSLF_READ) + || dfbDevice->height() != lastLockedHeight + || dfbDevice->memory() != lockedMemory) { + prepare(dfbDevice); + lastLockedHeight = dfbDevice->height(); + lockedMemory = dfbDevice->memory(); + } +} + +void QDirectFBPaintEnginePrivate::unlock() +{ + Q_ASSERT(dfbDevice); + dfbDevice->unlockDirectFB(); + lockedMemory = 0; +} + +void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) +{ + transform = m; + matrixRotShear = (transform.m12() != 0 || transform.m21() != 0); + if (qMin(transform.m11(), transform.m22()) < 0) { + scale = NegativeScale; + } else if (transform.m11() != 1 || transform.m22() != 1) { + scale = Scaled; + } else { + scale = NoScale; + } +} + +void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) +{ + lastLockedHeight = -1; + if (device->devType() == QInternal::CustomRaster) + dfbDevice = static_cast<QDirectFBPaintDevice*>(device); + else if (device->devType() == QInternal::Pixmap) { + QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data); + dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData); + } + + if (dfbDevice) + surface = dfbDevice->directFBSurface(); + + if (!surface) { + qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", + device->devType()); + } + lockedMemory = 0; + forceRasterPrimitives = dfbDevice->forceRasterPrimitives(); + + surface->GetSize(surface, &fbWidth, &fbHeight); + + setTransform(QTransform()); + antialiased = false; + opacity = 255; + setCompositionMode(q->state()->compositionMode()); + dirtyClip = true; + setPen(q->state()->pen); + setDFBColor(pen.color()); +} + +void QDirectFBPaintEnginePrivate::end() +{ + lockedMemory = 0; + dfbDevice = 0; + surface->ReleaseSource(surface); + surface->SetClip(surface, NULL); + surface = 0; +} + +void QDirectFBPaintEnginePrivate::setPen(const QPen &p) +{ + pen = p; + simplePen = (pen.style() == Qt::NoPen) || + (pen.style() == Qt::SolidLine + && !antialiased + && (pen.brush().style() == Qt::SolidPattern) + && (pen.widthF() <= 1 && scale != NoScale)); +} + +void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) +{ + blitFlagsFromCompositionMode = DSBLIT_NOFX; + drawFlagsFromCompositionMode = DSDRAW_NOFX; + + bool blend = true; + switch (mode) { + case QPainter::CompositionMode_SourceOver: + porterDuffRule = DSPD_SRC_OVER; + break; + case QPainter::CompositionMode_DestinationOver: + porterDuffRule = DSPD_DST_OVER; + break; + case QPainter::CompositionMode_Clear: + porterDuffRule = DSPD_CLEAR; + blend = false; + break; + case QPainter::CompositionMode_Source: + porterDuffRule = DSPD_SRC; + blend = false; + break; + case QPainter::CompositionMode_Destination: + porterDuffRule = DSPD_NONE; // ### need to double check this + blend = false; + return; + case QPainter::CompositionMode_SourceIn: + porterDuffRule = DSPD_SRC_IN; + break; + case QPainter::CompositionMode_DestinationIn: + porterDuffRule = DSPD_DST_IN; + break; + case QPainter::CompositionMode_SourceOut: + porterDuffRule = DSPD_SRC_OUT; + break; + case QPainter::CompositionMode_DestinationOut: + porterDuffRule = DSPD_DST_OUT; + break; + case QPainter::CompositionMode_Xor: + porterDuffRule = DSPD_XOR; + blitFlagsFromCompositionMode |= DSBLIT_XOR; + drawFlagsFromCompositionMode |= DSDRAW_XOR; + break; +// case QPainter::CompositionMode_Plus: // ??? +// porterDuffRule = DSPD_ADD; +// break; + default: + qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): " + "mode %d not implemented", mode); + return; + } + // intentially not comparing with current porterDuffRule. surface might have changed. + if (blend) { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL; + drawFlagsFromCompositionMode |= DSDRAW_BLEND; + } + if (opacity != 255) { + setOpacity(opacity); + } +} + +void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) +{ + opacity = op; + if (opacity == 255) { + blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA; + } else { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA; + } +} + +void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) +{ + const bool old = antialiased; + antialiased = bool(hints & QPainter::Antialiasing); + if (old != antialiased) { + setPen(q->state()->pen); + } +} + +void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) +{ + quint32 blittingFlags = blitFlagsFromCompositionMode; + if (alpha) { + surface->SetPorterDuff(surface, + (blittingFlags & DSBLIT_BLEND_COLORALPHA) + ? DSPD_NONE + : porterDuffRule); + } else { + blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; + surface->SetPorterDuff(surface, DSPD_NONE); + } + surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); + surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); +} + +void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) +{ + Q_ASSERT(surface); + const quint8 alpha = (opacity == 255 ? + color.alpha() : ALPHA_MUL(color.alpha(), opacity)); + surface->SetColor(surface, + color.red(), color.green(), color.blue(), alpha); + quint32 drawingFlags = drawFlagsFromCompositionMode; + if (alpha == 255) { + drawingFlags &= ~DSDRAW_BLEND; + } + surface->SetPorterDuff(surface, DSPD_NONE); + // PorterDuff messes up alpha values for primitives + surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags)); +} + +void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) +{ + for (int i = 0; i < n; ++i) { + const QLine l = transform.map(lines[i]); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); + } +} + +void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) +{ + for (int i = 0; i < n; ++i) { + const QLine l = transform.map(lines[i]).toLine(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); + } +} + +void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) +{ + Q_ASSERT(isSimpleBrush(q->state()->brush)); + setDFBColor(q->state()->brush.color()); + const QVector<QRect> rects = region.rects(); + const int n = rects.size(); + fillRects(rects.constData(), n); +} + +void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) +{ + for (int i = 0; i < n; ++i) { + const QRect r = transform.mapRect(rects[i]); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); + } +} + +void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) +{ + for (int i = 0; i < n; ++i) { + const QRect r = transform.mapRect(rects[i]).toRect(); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); + } +} + +void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) +{ + for (int i = 0; i < n; ++i) { + const QRect r = transform.mapRect(rects[i]); + surface->DrawRectangle(surface, r.x(), r.y(), + r.width() + 1, r.height() + 1); + } +} + +void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) +{ + for (int i = 0; i < n; ++i) { + const QRect r = transform.mapRect(rects[i]).toRect(); + surface->DrawRectangle(surface, r.x(), r.y(), + r.width() + 1, r.height() + 1); + } +} + +IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release) +{ +#ifndef QT_DIRECTFB_IMAGECACHE + *release = true; + return QDirectFBScreen::instance()->createDFBSurface(img, QDirectFBScreen::DontTrackSurface); +#else + const qint64 key = img.cacheKey(); + *release = false; + if (imageCache.contains(key)) { + return imageCache[key]->surface; + } + + const int cost = cacheCost(img); + const bool cache = cost <= imageCache.maxCost(); + QDirectFBScreen *screen = QDirectFBScreen::instance(); + const QImage::Format format = (img.format() == screen->alphaPixmapFormat() || QDirectFBPixmapData::hasAlphaChannel(img) + ? screen->alphaPixmapFormat() : screen->pixelFormat()); + + IDirectFBSurface *surface = screen->copyToDFBSurface(img, format, + cache + ? QDirectFBScreen::TrackSurface + : QDirectFBScreen::DontTrackSurface); + if (cache) { + CachedImage *cachedImage = new CachedImage; + const_cast<QImage&>(img).data_ptr()->is_cached = true; + cachedImage->surface = surface; + imageCache.insert(key, cachedImage, cost); + } else { + *release = true; + } + return surface; +#endif +} + + +void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, const QRectF &src) +{ + const QRect sr = src.toRect(); + const QRect dr = transform.mapRect(dest).toRect(); + const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; + DFBResult result; + + if (dr.size() == sr.size()) { + result = surface->Blit(surface, s, &sRect, dr.x(), dr.y()); + } else { + const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() }; + result = surface->StretchBlit(surface, s, &sRect, &dRect); + } + if (result != DFB_OK) + DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); +} + +void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, + const QPixmap &pixmap) +{ + prepareForBlit(pixmap.hasAlphaChannel()); + QPixmapData *data = pixmap.pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); + IDirectFBSurface *s = dfbData->directFBSurface(); + const QRect dr = transform.mapRect(dest).toRect(); + DFBResult result = DFB_OK; + + if (scale == NoScale && dr == QRect(0, 0, fbWidth, fbHeight)) { + result = surface->TileBlit(surface, s, 0, 0, 0); + } else if (scale == NoScale) { + const int dx = pixmap.width(); + const int dy = pixmap.height(); + const DFBRectangle rect = { 0, 0, dx, dy }; + QVarLengthArray<DFBRectangle> rects; + QVarLengthArray<DFBPoint> points; + + for (int y = dr.y(); y <= dr.bottom(); y += dy) { + for (int x = dr.x(); x <= dr.right(); x += dx) { + rects.append(rect); + const DFBPoint point = { x, y }; + points.append(point); + } + } + result = surface->BatchBlit(surface, s, rects.constData(), + points.constData(), points.size()); + } else { + const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); + const int dx = sr.width(); + const int dy = sr.height(); + const DFBRectangle sRect = { 0, 0, dx, dy }; + + for (int y = dr.y(); y <= dr.bottom(); y += dy) { + for (int x = dr.x(); x <= dr.right(); x += dx) { + const DFBRectangle dRect = { x, y, dx, dy }; + result = surface->StretchBlit(surface, s, &sRect, &dRect); + if (result != DFB_OK) { + y = dr.bottom() + 1; + break; + } + } + } + } + + if (result != DFB_OK) + DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); +} + +void QDirectFBPaintEnginePrivate::updateClip() +{ + if (!dirtyClip) + return; + + const QClipData *clipData = clip(); + if (!clipData || !clipData->enabled) { + surface->SetClip(surface, NULL); + dfbHandledClip = true; + } else if (clipData->hasRectClip) { + const DFBRegion r = { + clipData->clipRect.x(), + clipData->clipRect.y(), + clipData->clipRect.x() + clipData->clipRect.width(), + clipData->clipRect.y() + clipData->clipRect.height() + }; + surface->SetClip(surface, &r); + dfbHandledClip = true; + } else if (clipData->hasRegionClip && ignoreSystemClip && clipData->clipRegion == systemClip) { + dfbHandledClip = true; + } else { + dfbHandledClip = false; + } + + dirtyClip = false; +} + +void QDirectFBPaintEnginePrivate::systemStateChanged() +{ + dirtyClip = true; + QRasterPaintEnginePrivate::systemStateChanged(); +} + #endif // QT_NO_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h index e79ec61..d33255b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h @@ -106,6 +106,7 @@ public: virtual void clip(const QVectorPath &path, Qt::ClipOperation op); virtual void clip(const QRect &rect, Qt::ClipOperation op); + static void initImageCache(int size); }; QT_END_HEADER diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index ea9bb3a..7297a99 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -157,6 +157,16 @@ static bool checkForAlphaPixels(const QImage &img) return false; } +bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img) +{ +#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION + return ::checkForAlphaPixels(img); +#else + return img.hasAlphaChannel(); +#endif +} + + void QDirectFBPixmapData::fromImage(const QImage &i, Qt::ImageConversionFlags flags) { @@ -166,7 +176,7 @@ void QDirectFBPixmapData::fromImage(const QImage &i, const QImage img = (i.depth() == 1 ? i.convertToFormat(screen->alphaPixmapFormat()) : i); if (img.hasAlphaChannel() #ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION - && (flags & Qt::NoOpaqueDetection || ::checkForAlphaPixels(img)) + && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img)) #endif ) { alpha = true; @@ -357,7 +367,7 @@ QImage QDirectFBPixmapData::toImage() const return img->copy(); } -QPaintEngine* QDirectFBPixmapData::paintEngine() const +QPaintEngine *QDirectFBPixmapData::paintEngine() const { if (!engine) { // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass @@ -368,10 +378,15 @@ QPaintEngine* QDirectFBPixmapData::paintEngine() const return engine; } +QImage *QDirectFBPixmapData::buffer() +{ + lockDirectFB(DSLF_READ|DSLF_WRITE); + return lockedImage; +} -QImage* QDirectFBPixmapData::buffer() +QImage * QDirectFBPixmapData::buffer(uint lockFlags) { - lockDirectFB(); + lockDirectFB(lockFlags); return lockedImage; } @@ -381,3 +396,4 @@ void QDirectFBPixmapData::invalidate() alpha = false; format = QImage::Format_Invalid; } + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 6cfafcd..7cd60d6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -69,11 +69,13 @@ public: Qt::TransformationMode mode) const; QImage toImage() const; QPaintEngine* paintEngine() const; - QImage *buffer(); + virtual QImage *buffer(); + QImage *buffer(uint lockFlags); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} inline QImage::Format pixelFormat() const { return format; } + static bool hasAlphaChannel(const QImage &img); private: void invalidate(); QDirectFBPaintEngine *engine; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index c1b75c5..f571d1b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qdirectfbscreen.h" -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbpixmap.h" #include "qdirectfbmouse.h" #include "qdirectfbkeyboard.h" @@ -113,9 +113,9 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() delete keyboard; #endif - foreach (IDirectFBSurface *surf, allocatedSurfaces) - surf->Release(surf); - allocatedSurfaces.clear(); + for (QSet<IDirectFBSurface*>::const_iterator it = allocatedSurfaces.begin(); it != allocatedSurfaces.end(); ++it) { + (*it)->Release(*it); + } if (dfbSurface) dfbSurface->Release(dfbSurface); @@ -350,6 +350,7 @@ QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const { return d_ptr->directFBFlags; } + IDirectFB *QDirectFBScreen::dfb() { return d_ptr->dfb; @@ -751,43 +752,43 @@ struct FlagDescription { }; static const FlagDescription accelerationDescriptions[] = { - { "DFXL_NONE ", DFXL_NONE }, - { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE }, - { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE }, - { "DFXL_DRAWLINE", DFXL_DRAWLINE }, - { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE }, - { "DFXL_BLIT", DFXL_BLIT }, - { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT }, - { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES }, - { "DFXL_DRAWSTRING", DFXL_DRAWSTRING }, + { " DFXL_NONE ", DFXL_NONE }, + { " DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE }, + { " DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE }, + { " DFXL_DRAWLINE", DFXL_DRAWLINE }, + { " DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE }, + { " DFXL_BLIT", DFXL_BLIT }, + { " DFXL_STRETCHBLIT", DFXL_STRETCHBLIT }, + { " DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES }, + { " DFXL_DRAWSTRING", DFXL_DRAWSTRING }, { 0, 0 } }; static const FlagDescription blitDescriptions[] = { - { "DSBLIT_NOFX", DSBLIT_NOFX }, - { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL }, - { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA }, - { "DSBLIT_COLORIZE", DSBLIT_COLORIZE }, - { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY }, - { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY }, - { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY }, - { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY }, - { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY }, - { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE }, - { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR }, - { "DSBLIT_XOR", DSBLIT_XOR }, - { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION }, + { " DSBLIT_NOFX", DSBLIT_NOFX }, + { " DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL }, + { " DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA }, + { " DSBLIT_COLORIZE", DSBLIT_COLORIZE }, + { " DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY }, + { " DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY }, + { " DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY }, + { " DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY }, + { " DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY }, + { " DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE }, + { " DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR }, + { " DSBLIT_XOR", DSBLIT_XOR }, + { " DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION }, { 0, 0 } }; static const FlagDescription drawDescriptions[] = { - { "DSDRAW_NOFX", DSDRAW_NOFX }, - { "DSDRAW_BLEND", DSDRAW_BLEND }, - { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY }, - { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY }, - { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY }, - { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY }, - { "DSDRAW_XOR", DSDRAW_XOR }, + { " DSDRAW_NOFX", DSDRAW_NOFX }, + { " DSDRAW_BLEND", DSDRAW_BLEND }, + { " DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY }, + { " DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY }, + { " DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY }, + { " DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY }, + { " DSDRAW_XOR", DSDRAW_XOR }, { 0, 0 } }; #endif @@ -817,7 +818,7 @@ static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags -static void printDirectFBInfo(IDirectFB *fb) +static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface) { DFBResult result; DFBGraphicsDeviceDescription dev; @@ -828,10 +829,14 @@ static void printDirectFBInfo(IDirectFB *fb) return; } - qDebug("Device: %s (%s), Driver: %s v%i.%i (%s)\n" - " acceleration: 0x%x%s,\nblit: 0x%x%s,\ndraw: 0x%0x%s\nvideo: %iKB\n", + DFBSurfacePixelFormat pixelFormat; + primarySurface->GetPixelFormat(primarySurface, &pixelFormat); + + qDebug("Device: %s (%s), Driver: %s v%i.%i (%s) Pixelformat: %d (%d)\n" + "acceleration: 0x%x%s\nblit: 0x%x%s\ndraw: 0x%0x%s\nvideo: %iKB\n", dev.name, dev.vendor, dev.driver.name, dev.driver.major, - dev.driver.minor, dev.driver.vendor, dev.acceleration_mask, + dev.driver.minor, dev.driver.vendor, DFB_PIXELFORMAT_INDEX(pixelFormat), + QDirectFBScreen::getImageFormat(primarySurface), dev.acceleration_mask, ::flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(), dev.blitting_flags, ::flagDescriptions(dev.blitting_flags, blitDescriptions).constData(), dev.drawing_flags, ::flagDescriptions(dev.drawing_flags, drawDescriptions).constData(), @@ -882,9 +887,6 @@ bool QDirectFBScreen::connect(const QString &displaySpec) return false; } - if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive)) - printDirectFBInfo(d_ptr->dfb); - if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive)) d_ptr->directFBFlags |= VideoOnly; @@ -900,6 +902,12 @@ bool QDirectFBScreen::connect(const QString &displaySpec) d_ptr->directFBFlags |= BoundingRectFlip; } +#ifdef QT_DIRECTFB_IMAGECACHE + int imageCacheSize = 4 * 1024 * 1024; // 4 MB + ::setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize); + QDirectFBPaintEngine::initImageCache(imageCacheSize); +#endif + if (displayArgs.contains(QLatin1String("ignoresystemclip"), Qt::CaseInsensitive)) d_ptr->directFBFlags |= IgnoreSystemClip; @@ -945,6 +953,9 @@ bool QDirectFBScreen::connect(const QString &displaySpec) return false; } + if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive)) + printDirectFBInfo(d_ptr->dfb, d_ptr->dfbSurface); + // Work out what format we're going to use for surfaces with an alpha channel d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(d_ptr->dfbSurface); setPixelFormat(d_ptr->alphaPixmapFormat); @@ -1102,19 +1113,19 @@ QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM if (QApplication::type() == QApplication::GuiServer) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); } else { return QScreen::createSurface(widget); } #else - return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); #endif } QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const { if (key == QLatin1String("directfb")) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this)); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this)); } return QScreen::createSurface(key); } @@ -1147,7 +1158,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface); + QDirectFBWindowSurface *s = static_cast<QDirectFBWindowSurface*>(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); @@ -1196,7 +1207,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface); + QDirectFBWindowSurface *s = static_cast<QDirectFBWindowSurface*>(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); @@ -1336,12 +1347,12 @@ bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *d return true; } -uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl) +uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, uint flags, int *bpl) { void *mem; - const DFBResult result = surface->Lock(surface, flags, static_cast<void**>(&mem), bpl); + const DFBResult result = surface->Lock(surface, static_cast<DFBSurfaceLockFlags>(flags), static_cast<void**>(&mem), bpl); if (result != DFB_OK) { - DirectFBError("QDirectFBPixmapData::lockSurface()", result); + DirectFBError("QDirectFBScreen::lockSurface()", result); } return reinterpret_cast<uchar*>(mem); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 42d0ebe..84199a2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -105,8 +105,6 @@ public: TrackSurface = 1 }; Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption); - IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc, - SurfaceCreationOptions options); IDirectFBSurface *createDFBSurface(const QImage &image, SurfaceCreationOptions options); IDirectFBSurface *createDFBSurface(const QSize &size, @@ -130,6 +128,7 @@ public: static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format); static inline bool isPremultiplied(QImage::Format format); static inline bool hasAlpha(DFBSurfacePixelFormat format); + static inline bool hasAlpha(IDirectFBSurface *surface); QImage::Format alphaPixmapFormat() const; #ifndef QT_NO_DIRECTFB_PALETTE @@ -137,14 +136,17 @@ public: const QImage &image); #endif - static uchar *lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl = 0); + static uchar *lockSurface(IDirectFBSurface *surface, uint flags, int *bpl = 0); private: + IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc, + SurfaceCreationOptions options); void compose(const QRegion &r); void blit(IDirectFBSurface *src, const QPoint &topLeft, const QRegion ®ion); QDirectFBScreenPrivate *d_ptr; + friend class SurfaceCache; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions); @@ -186,6 +188,14 @@ inline bool QDirectFBScreen::hasAlpha(DFBSurfacePixelFormat format) } } +inline bool QDirectFBScreen::hasAlpha(IDirectFBSurface *surface) +{ + Q_ASSERT(surface); + DFBSurfacePixelFormat format; + surface->GetPixelFormat(surface, &format); + return QDirectFBScreen::hasAlpha(format); +} + QT_END_HEADER #endif // QDIRECTFBSCREEN_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index beb9b5f..f1e3c84 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbscreen.h" #include "qdirectfbpaintengine.h" @@ -50,7 +50,7 @@ //#define QT_DIRECTFB_DEBUG_SURFACES 1 -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) : QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) @@ -66,7 +66,7 @@ QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *sc #endif } -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) @@ -86,17 +86,17 @@ QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *sc #endif } -QDirectFBSurface::~QDirectFBSurface() +QDirectFBWindowSurface::~QDirectFBWindowSurface() { } -bool QDirectFBSurface::isValid() const +bool QDirectFBWindowSurface::isValid() const { return true; } #ifndef QT_NO_DIRECTFB_WM -void QDirectFBSurface::createWindow() +void QDirectFBWindowSurface::createWindow() { #ifdef QT_NO_DIRECTFB_LAYER #warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM @@ -132,7 +132,7 @@ void QDirectFBSurface::createWindow() } #endif // QT_NO_DIRECTFB_WM -void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) +void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) { if (rect.isNull()) { #ifndef QT_NO_DIRECTFB_WM @@ -211,13 +211,13 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) } if (result != DFB_OK) - DirectFBErrorFatal("QDirectFBSurface::setGeometry()", result); + DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); } QWSWindowSurface::setGeometry(rect, mask); } -QByteArray QDirectFBSurface::permanentState() const +QByteArray QDirectFBWindowSurface::permanentState() const { QByteArray array; #ifdef QT_NO_DIRECTFB_WM @@ -236,7 +236,7 @@ QByteArray QDirectFBSurface::permanentState() const return array; } -void QDirectFBSurface::setPermanentState(const QByteArray &state) +void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) { SurfaceFlags flags; const char *ptr = state.constData(); @@ -250,7 +250,7 @@ void QDirectFBSurface::setPermanentState(const QByteArray &state) #endif } -bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) +bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) { if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) return false; @@ -278,7 +278,7 @@ bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) return true; } -bool QDirectFBSurface::move(const QPoint &offset) +bool QDirectFBWindowSurface::move(const QPoint &offset) { QWSWindowSurface::move(offset); @@ -293,7 +293,7 @@ bool QDirectFBSurface::move(const QPoint &offset) #endif } -QRegion QDirectFBSurface::move(const QPoint &offset, const QRegion &newClip) +QRegion QDirectFBWindowSurface::move(const QPoint &offset, const QRegion &newClip) { #ifdef QT_NO_DIRECTFB_WM return QWSWindowSurface::move(offset, newClip); @@ -306,10 +306,10 @@ QRegion QDirectFBSurface::move(const QPoint &offset, const QRegion &newClip) #endif } -QPaintEngine* QDirectFBSurface::paintEngine() const +QPaintEngine* QDirectFBWindowSurface::paintEngine() const { if (!engine) { - QDirectFBSurface *that = const_cast<QDirectFBSurface*>(this); + QDirectFBWindowSurface *that = const_cast<QDirectFBWindowSurface*>(this); that->engine = new QDirectFBPaintEngine(that); return that->engine; } @@ -339,7 +339,7 @@ inline bool isWidgetOpaque(const QWidget *w) return false; } -void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, +void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(widget); @@ -402,15 +402,15 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, } -void QDirectFBSurface::beginPaint(const QRegion &) +void QDirectFBWindowSurface::beginPaint(const QRegion &) { } -void QDirectFBSurface::endPaint(const QRegion &) +void QDirectFBWindowSurface::endPaint(const QRegion &) { #ifdef QT_DIRECTFB_DEBUG_SURFACES if (bufferImages.count()) { - qDebug("QDirectFBSurface::endPaint() this=%p", this); + qDebug("QDirectFBWindowSurface::endPaint() this=%p", this); foreach(QImage* bufferImg, bufferImages) qDebug(" Deleting buffer image %p", bufferImg); @@ -423,7 +423,7 @@ void QDirectFBSurface::endPaint(const QRegion &) } -QImage* QDirectFBSurface::buffer(const QWidget *widget) +QImage *QDirectFBWindowSurface::buffer(const QWidget *widget) { if (!lockedImage) return 0; @@ -441,7 +441,7 @@ QImage* QDirectFBSurface::buffer(const QWidget *widget) bufferImages.append(img); #ifdef QT_DIRECTFB_DEBUG_SURFACES - qDebug("QDirectFBSurface::buffer() Created & returned %p", img); + qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img); #endif return img; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 54c14a5..75998c4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -58,12 +58,12 @@ QT_BEGIN_HEADER QT_MODULE(Gui) -class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice +class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice { public: - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); - ~QDirectFBSurface(); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); + ~QDirectFBWindowSurface(); bool isValid() const; @@ -79,15 +79,15 @@ public: QRegion move(const QPoint &offset, const QRegion &newClip); QImage image() const { return QImage(); } - QPaintDevice* paintDevice() { return this; } - QPaintEngine* paintEngine() const; + QPaintDevice *paintDevice() { return this; } + QPaintEngine *paintEngine() const; void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); void beginPaint(const QRegion &); void endPaint(const QRegion &); - QImage* buffer(const QWidget *widget); + QImage *buffer(const QWidget *widget); private: #ifndef QT_NO_DIRECTFB_WM diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro b/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro index b62894d..9331d0a 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro @@ -22,3 +22,5 @@ LIBS += -lpvr2d DESTDIR = $$QMAKE_LIBDIR_QT target.path = $$[QT_INSTALL_LIBS] INSTALLS += target + +include(../powervr.pri)
\ No newline at end of file diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README index ec02efb..4dce87f 100644 --- a/src/plugins/gfxdrivers/powervr/README +++ b/src/plugins/gfxdrivers/powervr/README @@ -29,12 +29,13 @@ strictly Unix-style markers. *************************************************************************** * IMPORTANT: To build the QScreen plugin and the WSEGL library it depends * -* on, the pvr2d.h, wsegl.h headers for your platform are required. These * -* can be obtained either through your platform provider or directly from * -* Imagination Technologies. * +* on, the pvr2d.h, wsegl.h headers for your platform are required. You * +* can find a copy of these headers in src/3rdparty/powervr for SGX based * +* platforms like the TI OMAP3xxx. They may also work on MBX platforms too * +* depending on how old your libEGL is. You can tell Qt where to find * +* these headers by setting QMAKE_INCDIR_POWERVR in the mkspec. * *************************************************************************** - When you start a Qt/Embedded application, you should modify the QWS_DISPLAY environment variable to use the "powervr" driver instead of "LinuxFb". For example, if your original QWS_DISPLAY variable was: diff --git a/src/plugins/gfxdrivers/powervr/powervr.pri b/src/plugins/gfxdrivers/powervr/powervr.pri new file mode 100644 index 0000000..9df8c0e --- /dev/null +++ b/src/plugins/gfxdrivers/powervr/powervr.pri @@ -0,0 +1,2 @@ + +INCLUDEPATH += $$QMAKE_INCDIR_POWERVR diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro index 691cd2d..675be85 100644 --- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro +++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro @@ -9,9 +9,10 @@ DEFINES += QT_QWS_CLIENTBLIT INCLUDEPATH += ../QWSWSEGL + HEADERS = \ - pvreglscreen.h \ - pvreglwindowsurface.h + pvreglscreen.h \ + pvreglwindowsurface.h SOURCES = \ pvreglscreenplugin.cpp \ @@ -22,3 +23,5 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target + +include(../powervr.pri)
\ No newline at end of file diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index a84e840..1f54db7 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -224,7 +224,7 @@ static QTextCodec* codec(MYSQL* mysql) static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QMYSQLDriverPrivate* p) { - const char *cerr = mysql_error(p->mysql); + const char *cerr = p->mysql ? mysql_error(p->mysql) : 0; return QSqlError(QLatin1String("QMYSQL: ") + err, p->tc ? toUnicode(p->tc, cerr) : QString::fromLatin1(cerr), type, mysql_errno(p->mysql)); |