Merge pull request #3537 from akallabeth/gdi_speedup

Inlined heavily used functions.
This commit is contained in:
Bernhard Miklautz 2016-10-13 10:28:57 +02:00 committed by GitHub
commit de44204683
7 changed files with 180 additions and 128 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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
}

View File

@ -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)
{

View File

@ -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 */

View File

@ -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);