Merge pull request #3537 from akallabeth/gdi_speedup
Inlined heavily used functions.
This commit is contained in:
commit
de44204683
@ -532,8 +532,6 @@ FREERDP_API DWORD gdi_rop3_code(BYTE code);
|
||||
FREERDP_API UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip);
|
||||
FREERDP_API BOOL gdi_decode_color(rdpGdi* gdi, const UINT32 srcColor,
|
||||
UINT32* color, UINT32* format);
|
||||
FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, UINT32 x, UINT32 y);
|
||||
FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, UINT32 x, UINT32 y);
|
||||
FREERDP_API BOOL gdi_resize(rdpGdi* gdi, UINT32 width, UINT32 height);
|
||||
FREERDP_API BOOL gdi_resize_ex(rdpGdi* gdi, UINT32 width, UINT32 height,
|
||||
UINT32 stride, UINT32 format, BYTE* buffer,
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
#include "../gdi/gdi.h"
|
||||
|
||||
#define TAG FREERDP_TAG("gdi.bitmap")
|
||||
|
||||
@ -272,10 +273,10 @@ static UINT32 process_rop(UINT32 src, UINT32 dst, UINT32 pat, const char* rop,
|
||||
return stack[0];
|
||||
}
|
||||
|
||||
static BOOL BitBlt_write(HGDI_DC hdcDest, HGDI_DC hdcSrc, UINT32 nXDest,
|
||||
UINT32 nYDest, UINT32 nXSrc, UINT32 nYSrc, UINT32 x, UINT32 y,
|
||||
BOOL useSrc, BOOL usePat, UINT32 style,
|
||||
const char* rop, const gdiPalette* palette)
|
||||
static INLINE BOOL BitBlt_write(HGDI_DC hdcDest, HGDI_DC hdcSrc, UINT32 nXDest,
|
||||
UINT32 nYDest, UINT32 nXSrc, UINT32 nYSrc, UINT32 x, UINT32 y,
|
||||
BOOL useSrc, BOOL usePat, UINT32 style,
|
||||
const char* rop, const gdiPalette* palette)
|
||||
{
|
||||
UINT32 dstColor;
|
||||
UINT32 colorA;
|
||||
@ -461,6 +462,8 @@ BOOL gdi_BitBlt(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
|
||||
UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
|
||||
UINT32 nXSrc, UINT32 nYSrc, DWORD rop, const gdiPalette* palette)
|
||||
{
|
||||
HGDI_BITMAP hSrcBmp, hDstBmp;
|
||||
|
||||
if (!hdcDest)
|
||||
return FALSE;
|
||||
|
||||
@ -468,10 +471,44 @@ BOOL gdi_BitBlt(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
|
||||
&nYSrc))
|
||||
return TRUE;
|
||||
|
||||
if (!BitBlt_process(hdcDest, nXDest, nYDest,
|
||||
nWidth, nHeight, hdcSrc,
|
||||
nXSrc, nYSrc, gdi_rop_to_string(rop), palette))
|
||||
return FALSE;
|
||||
/* Check which ROP should be performed.
|
||||
* Some specific ROP are used heavily and are resource intensive,
|
||||
* add optimized versions for these here.
|
||||
*
|
||||
* For all others fall back to the generic implementation.
|
||||
*/
|
||||
switch (rop)
|
||||
{
|
||||
case GDI_SRCCOPY:
|
||||
hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
|
||||
hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject;
|
||||
|
||||
if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline,
|
||||
nXDest, nYDest, nWidth, nHeight,
|
||||
hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case GDI_DSTCOPY:
|
||||
hSrcBmp = (HGDI_BITMAP) hdcDest->selectedObject;
|
||||
hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject;
|
||||
|
||||
if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline,
|
||||
nXDest, nYDest, nWidth, nHeight,
|
||||
hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!BitBlt_process(hdcDest, nXDest, nYDest,
|
||||
nWidth, nHeight, hdcSrc,
|
||||
nXSrc, nYSrc, gdi_rop_to_string(rop), palette))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight))
|
||||
return FALSE;
|
||||
|
@ -866,10 +866,4 @@ HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp)
|
||||
hBrush->pattern = hbmp;
|
||||
return hBrush;
|
||||
}
|
||||
UINT32 gdi_GetBrushStyle(HGDI_DC hdc)
|
||||
{
|
||||
if (!hdc || !hdc->brush)
|
||||
return GDI_BS_NULL;
|
||||
|
||||
return hdc->brush->style;
|
||||
}
|
||||
|
@ -34,7 +34,14 @@ FREERDP_LOCAL const char* gdi_rop_to_string(UINT32 code);
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreateSolidBrush(UINT32 crColor);
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp);
|
||||
FREERDP_LOCAL UINT32 gdi_GetBrushStyle(HGDI_DC hdc);
|
||||
|
||||
static INLINE UINT32 gdi_GetBrushStyle(HGDI_DC hdc)
|
||||
{
|
||||
if (!hdc || !hdc->brush)
|
||||
return GDI_BS_NULL;
|
||||
|
||||
return hdc->brush->style;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -369,65 +369,6 @@ UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip)
|
||||
return format;
|
||||
}
|
||||
|
||||
BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, UINT32 x, UINT32 y)
|
||||
{
|
||||
BYTE* p;
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP) hdcBmp->selectedObject;
|
||||
|
||||
if (x < hBmp->width && y < hBmp->height)
|
||||
{
|
||||
p = hBmp->data + (y * hBmp->scanline) + (x * GetBytesPerPixel(hdcBmp->format));
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d",
|
||||
x, y, hBmp->width, hBmp->height);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current color in brush bitmap according to dest coordinates.\n
|
||||
* @msdn{dd183396}
|
||||
* @param x dest x-coordinate
|
||||
* @param y dest y-coordinate
|
||||
* @return color
|
||||
*/
|
||||
BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, UINT32 x, UINT32 y)
|
||||
{
|
||||
BYTE* p;
|
||||
UINT32 brushStyle = gdi_GetBrushStyle(hdcBrush);
|
||||
|
||||
switch (brushStyle)
|
||||
{
|
||||
case GDI_BS_PATTERN:
|
||||
case GDI_BS_HATCHED:
|
||||
{
|
||||
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
|
||||
/* According to @msdn{dd183396}, the system always positions a brush bitmap
|
||||
* at the brush origin and copy across the client area.
|
||||
* Calculate the offset of the mapped pixel in the brush bitmap according to
|
||||
* brush origin and dest coordinates */
|
||||
x = (x + hBmpBrush->width - (hdcBrush->brush->nXOrg % hBmpBrush->width)) %
|
||||
hBmpBrush->width;
|
||||
y = (y + hBmpBrush->height - (hdcBrush->brush->nYOrg % hBmpBrush->height)) %
|
||||
hBmpBrush->height;
|
||||
p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * GetBytesPerPixel(
|
||||
hBmpBrush->format));
|
||||
return p;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p = (BYTE*) & (hdcBrush->textColor);
|
||||
return p;
|
||||
}
|
||||
|
||||
gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp,
|
||||
BYTE* data)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define __GDI_CORE_H
|
||||
|
||||
#include "graphics.h"
|
||||
#include "brush.h"
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
@ -32,4 +33,63 @@ FREERDP_LOCAL gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height,
|
||||
BYTE* data);
|
||||
FREERDP_LOCAL void gdi_bitmap_free_ex(gdiBitmap* gdi_bmp);
|
||||
|
||||
static INLINE BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, UINT32 x, UINT32 y)
|
||||
{
|
||||
BYTE* p;
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP) hdcBmp->selectedObject;
|
||||
|
||||
if (x < hBmp->width && y < hBmp->height)
|
||||
{
|
||||
p = hBmp->data + (y * hBmp->scanline) + (x * GetBytesPerPixel(hdcBmp->format));
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(FREERDP_TAG("gdi"),
|
||||
"gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d",
|
||||
x, y, hBmp->width, hBmp->height);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current color in brush bitmap according to dest coordinates.\n
|
||||
* @msdn{dd183396}
|
||||
* @param x dest x-coordinate
|
||||
* @param y dest y-coordinate
|
||||
* @return color
|
||||
*/
|
||||
static INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, UINT32 x, UINT32 y)
|
||||
{
|
||||
BYTE* p;
|
||||
UINT32 brushStyle = gdi_GetBrushStyle(hdcBrush);
|
||||
|
||||
switch (brushStyle)
|
||||
{
|
||||
case GDI_BS_PATTERN:
|
||||
case GDI_BS_HATCHED:
|
||||
{
|
||||
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
|
||||
/* According to @msdn{dd183396}, the system always positions a brush bitmap
|
||||
* at the brush origin and copy across the client area.
|
||||
* Calculate the offset of the mapped pixel in the brush bitmap according to
|
||||
* brush origin and dest coordinates */
|
||||
x = (x + hBmpBrush->width - (hdcBrush->brush->nXOrg % hBmpBrush->width)) %
|
||||
hBmpBrush->width;
|
||||
y = (y + hBmpBrush->height - (hdcBrush->brush->nYOrg % hBmpBrush->height)) %
|
||||
hBmpBrush->height;
|
||||
p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * GetBytesPerPixel(
|
||||
hBmpBrush->format));
|
||||
return p;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p = (BYTE*) & (hdcBrush->textColor);
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif /* __GDI_CORE_H */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include "clipping.h"
|
||||
#include "../gdi/gdi.h"
|
||||
|
||||
#define TAG FREERDP_TAG("gdi.shape")
|
||||
|
||||
@ -108,7 +109,7 @@ static void Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2)
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect,
|
||||
int nBottomRect)
|
||||
int nBottomRect)
|
||||
{
|
||||
Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
||||
return TRUE;
|
||||
@ -130,6 +131,7 @@ BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_RECT rect, HGDI_BRUSH hbr)
|
||||
BOOL monochrome = FALSE;
|
||||
UINT32 nXDest, nYDest;
|
||||
UINT32 nWidth, nHeight;
|
||||
const BYTE* srcp;
|
||||
gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
|
||||
|
||||
if (!hdc || !hbr)
|
||||
@ -138,60 +140,73 @@ BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_RECT rect, HGDI_BRUSH hbr)
|
||||
if (!gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL))
|
||||
return TRUE;
|
||||
|
||||
switch(hbr->style)
|
||||
switch (hbr->style)
|
||||
{
|
||||
case GDI_BS_SOLID:
|
||||
color = hbr->color;
|
||||
case GDI_BS_SOLID:
|
||||
color = hbr->color;
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x,
|
||||
nYDest + y);
|
||||
|
||||
if (dstp)
|
||||
WriteColor(dstp, hdc->format, color);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
const UINT32 yOffset = ((nYDest + y) * hbr->pattern->width % hbr->pattern->height) * GetBytesPerPixel(hbr->pattern->format);
|
||||
const UINT32 xOffset = ((nXDest + x) % hbr->pattern->width) * GetBytesPerPixel(hbr->pattern->format);
|
||||
const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x,
|
||||
nYDest + y);
|
||||
|
||||
if (!patp)
|
||||
return FALSE;
|
||||
if (monochrome)
|
||||
{
|
||||
if (*patp == 0)
|
||||
dstColor = hdc->bkColor;
|
||||
else
|
||||
dstColor = hdc->textColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstColor = ReadColor(patp, hbr->pattern->format);
|
||||
dstColor = ConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
|
||||
}
|
||||
nYDest);
|
||||
|
||||
if (dstp)
|
||||
WriteColor(dstp, hdc->format, dstColor);
|
||||
WriteColor(dstp, hdc->format, color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
|
||||
|
||||
for (y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||
memcpy(dstp, srcp, nWidth * GetBytesPerPixel(hdc->format));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
const UINT32 yOffset = ((nYDest + y) * hbr->pattern->width %
|
||||
hbr->pattern->height) * GetBytesPerPixel(hbr->pattern->format);
|
||||
const UINT32 xOffset = ((nXDest + x) % hbr->pattern->width) * GetBytesPerPixel(
|
||||
hbr->pattern->format);
|
||||
const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x,
|
||||
nYDest + y);
|
||||
|
||||
if (!patp)
|
||||
return FALSE;
|
||||
|
||||
if (monochrome)
|
||||
{
|
||||
if (*patp == 0)
|
||||
dstColor = hdc->bkColor;
|
||||
else
|
||||
dstColor = hdc->textColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstColor = ReadColor(patp, hbr->pattern->format);
|
||||
dstColor = ConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
|
||||
}
|
||||
|
||||
if (dstp)
|
||||
WriteColor(dstp, hdc->format, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight))
|
||||
return FALSE;
|
||||
|
||||
@ -223,14 +238,14 @@ BOOL gdi_Polygon(HGDI_DC hdc, GDI_POINT* lpPoints, int nCount)
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT* lpPoints, int* lpPolyCounts,
|
||||
int nCount)
|
||||
int nCount)
|
||||
{
|
||||
WLog_ERR(TAG, "Not implemented!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL gdi_Rectangle(HGDI_DC hdc, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
|
||||
UINT32 nHeight)
|
||||
UINT32 nHeight)
|
||||
{
|
||||
UINT32 x, y;
|
||||
UINT32 color;
|
||||
@ -244,9 +259,9 @@ BOOL gdi_Rectangle(HGDI_DC hdc, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstLeft = gdi_get_bitmap_pointer(hdc, nXDst,
|
||||
nYDst + y);
|
||||
nYDst + y);
|
||||
BYTE* dstRight = gdi_get_bitmap_pointer(hdc, nXDst + nWidth - 1,
|
||||
nYDst + y);
|
||||
nYDst + y);
|
||||
|
||||
if (dstLeft)
|
||||
WriteColor(dstLeft, hdc->format, color);
|
||||
@ -258,9 +273,9 @@ BOOL gdi_Rectangle(HGDI_DC hdc, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
BYTE* dstTop = gdi_get_bitmap_pointer(hdc, nXDst + x,
|
||||
nYDst);
|
||||
nYDst);
|
||||
BYTE* dstBottom = gdi_get_bitmap_pointer(hdc, nXDst + x,
|
||||
nYDst + nHeight - 1);
|
||||
nYDst + nHeight - 1);
|
||||
|
||||
if (dstTop)
|
||||
WriteColor(dstTop, hdc->format, color);
|
||||
|
Loading…
Reference in New Issue
Block a user