From b6284c7f8a0b9de4ae9422fde052bcca21c6b1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 29 Sep 2011 23:58:34 +0000 Subject: [PATCH] * Moved the SIMD code from AppServer.cpp to Painter.cpp where it is actually needed. It might be best to put it into its own file, though. * This is required in order to let our test environment work with the stricter runtime_loader we have now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42787 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/AppServer.cpp | 70 +----------------- src/servers/app/AppServer.h | 10 +-- src/servers/app/drawing/Painter/Painter.cpp | 82 ++++++++++++++++++++- src/servers/app/drawing/Painter/Painter.h | 30 +++----- 4 files changed, 95 insertions(+), 97 deletions(-) diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 655fa03f42..76e09927c3 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2010, Haiku, Inc. + * Copyright 2001-2011, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -40,71 +40,6 @@ BTokenSpace gTokenSpace; uint32 gAppServerSIMDFlags = 0; -/*! Detect SIMD flags for use in AppServer. Checks all CPUs in the system - and chooses the minimum supported set of instructions. -*/ -static void -detect_simd() -{ -#if __INTEL__ - // Only scan CPUs for which we are certain the SIMD flags are properly - // defined. - const char* vendorNames[] = { - "GenuineIntel", - "AuthenticAMD", - "CentaurHauls", // Via CPUs, MMX and SSE support - "RiseRiseRise", // should be MMX-only - "CyrixInstead", // MMX-only, but custom MMX extensions - "GenuineTMx86", // MMX and SSE - 0 - }; - - system_info systemInfo; - if (get_system_info(&systemInfo) != B_OK) - return; - - // We start out with all flags set and end up with only those flags - // supported across all CPUs found. - uint32 appServerSIMD = 0xffffffff; - - for (int32 cpu = 0; cpu < systemInfo.cpu_count; cpu++) { - cpuid_info cpuInfo; - get_cpuid(&cpuInfo, 0, cpu); - - // Get the vendor string and terminate it manually - char vendor[13]; - memcpy(vendor, cpuInfo.eax_0.vendor_id, 12); - vendor[12] = 0; - - bool vendorFound = false; - for (uint32 i = 0; vendorNames[i] != 0; i++) { - if (strcmp(vendor, vendorNames[i]) == 0) - vendorFound = true; - } - - uint32 cpuSIMD = 0; - uint32 maxStdFunc = cpuInfo.regs.eax; - if (vendorFound && maxStdFunc >= 1) { - get_cpuid(&cpuInfo, 1, 0); - uint32 edx = cpuInfo.regs.edx; - if (edx & (1 << 23)) - cpuSIMD |= APPSERVER_SIMD_MMX; - if (edx & (1 << 25)) - cpuSIMD |= APPSERVER_SIMD_SSE; - } else { - // no flags can be identified - cpuSIMD = 0; - } - appServerSIMD &= cpuSIMD; - } - gAppServerSIMDFlags = appServerSIMD; -#endif // __INTEL__ -} - - -// #pragma mark - - - /*! \brief Constructor This loads the default fonts, allocates all the major global variables, @@ -128,9 +63,6 @@ AppServer::AppServer() sAppServer = this; - // Initialize SIMD flags - detect_simd(); - gInputManager = new InputManager(); // Create the font server and scan the proper directories. diff --git a/src/servers/app/AppServer.h b/src/servers/app/AppServer.h index cffa5b3fd4..6aaf5b5f56 100644 --- a/src/servers/app/AppServer.h +++ b/src/servers/app/AppServer.h @@ -1,8 +1,9 @@ /* - * Copyright (c) 2001-2005, Haiku, Inc. + * Copyright 2001-2011, Haiku, Inc. * Distributed under the terms of the MIT license. * - * Author: DarkWyrm + * Authors: + * DarkWyrm */ #ifndef APP_SERVER_H #define APP_SERVER_H @@ -54,12 +55,9 @@ class AppServer : public MessageLooper { BLocker fDesktopLock; }; + extern BitmapManager *gBitmapManager; extern port_id gAppServerPort; -extern uint32 gAppServerSIMDFlags; -// Defines for SIMD support. Early implementation, subject to change -#define APPSERVER_SIMD_MMX (1 << 0) -#define APPSERVER_SIMD_SSE (1 << 1) #endif /* APP_SERVER_H */ diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 1a8ef424d9..d23a0a6d1a 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -81,8 +81,86 @@ using std::nothrow; #define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1); #define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return; +// Defines for SIMD support. +#define APPSERVER_SIMD_MMX (1 << 0) +#define APPSERVER_SIMD_SSE (1 << 1) + +// Prototypes for assembler routines +extern "C" { + void bilinear_scale_xloop_mmxsse(const uint8* src, void* dst, + void* xWeights, uint32 xmin, uint32 xmax, uint32 wTop, uint32 srcBPR); +} + +static uint32 detect_simd(); + +static uint32 sSIMDFlags = detect_simd(); + + +/*! Detect SIMD flags for use in AppServer. Checks all CPUs in the system + and chooses the minimum supported set of instructions. +*/ +static uint32 +detect_simd() +{ +#if __INTEL__ + // Only scan CPUs for which we are certain the SIMD flags are properly + // defined. + const char* vendorNames[] = { + "GenuineIntel", + "AuthenticAMD", + "CentaurHauls", // Via CPUs, MMX and SSE support + "RiseRiseRise", // should be MMX-only + "CyrixInstead", // MMX-only, but custom MMX extensions + "GenuineTMx86", // MMX and SSE + 0 + }; + + system_info systemInfo; + if (get_system_info(&systemInfo) != B_OK) + return 0; + + // We start out with all flags set and end up with only those flags + // supported across all CPUs found. + uint32 systemSIMD = 0xffffffff; + + for (int32 cpu = 0; cpu < systemInfo.cpu_count; cpu++) { + cpuid_info cpuInfo; + get_cpuid(&cpuInfo, 0, cpu); + + // Get the vendor string and terminate it manually + char vendor[13]; + memcpy(vendor, cpuInfo.eax_0.vendor_id, 12); + vendor[12] = 0; + + bool vendorFound = false; + for (uint32 i = 0; vendorNames[i] != 0; i++) { + if (strcmp(vendor, vendorNames[i]) == 0) + vendorFound = true; + } + + uint32 cpuSIMD = 0; + uint32 maxStdFunc = cpuInfo.regs.eax; + if (vendorFound && maxStdFunc >= 1) { + get_cpuid(&cpuInfo, 1, 0); + uint32 edx = cpuInfo.regs.edx; + if (edx & (1 << 23)) + cpuSIMD |= APPSERVER_SIMD_MMX; + if (edx & (1 << 25)) + cpuSIMD |= APPSERVER_SIMD_SSE; + } else { + // no flags can be identified + cpuSIMD = 0; + } + systemSIMD &= cpuSIMD; + } + return systemSIMD; +#endif // __INTEL__ +} + + +// #pragma mark - + -// constructor Painter::Painter() : fBuffer(), @@ -2314,7 +2392,7 @@ Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer, int codeSelect = kUseDefaultVersion; uint32 neededSIMDFlags = APPSERVER_SIMD_MMX | APPSERVER_SIMD_SSE; - if ((gAppServerSIMDFlags & neededSIMDFlags) == neededSIMDFlags) + if ((sSIMDFlags & neededSIMDFlags) == neededSIMDFlags) codeSelect = kUseSIMDVersion; else { if (xScale == yScale && (xScale == 1.5 || xScale == 2.0 diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 5192ceae65..645c95b6fc 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -7,10 +7,10 @@ * rendering pipe-lines for stroke, fills, bitmap and text rendering. * */ - #ifndef PAINTER_H #define PAINTER_H + #include "AGGTextRenderer.h" #include "FontManager.h" #include "PatternHandler.h" @@ -25,14 +25,6 @@ #include -// Prototypes for assembler routines -extern "C" { - void bilinear_scale_xloop_mmxsse(const uint8* src, void* dst, void* xWeights, - uint32 xmin, uint32 xmax, uint32 wTop, uint32 srcBPR ); -} - -extern uint32 gAppServerSIMDFlags; - class BBitmap; class BRegion; class BGradient; @@ -115,14 +107,14 @@ public: BRect FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3, const BGradient& gradient) const; - + // polygons BRect DrawPolygon(BPoint* ptArray, int32 numPts, bool filled, bool closed) const; BRect FillPolygon(BPoint* ptArray, int32 numPts, const BGradient& gradient, bool closed) const; - + // bezier curves BRect DrawBezier(BPoint* controlPoints, bool filled) const; @@ -141,7 +133,7 @@ public: const BGradient& gradient, const BPoint& viewToScreenOffset, float viewScale) const; - + // rects BRect StrokeRect(const BRect& r) const; @@ -156,14 +148,14 @@ public: // fills a solid rect with color c, no blending void FillRect(const BRect& r, const rgb_color& c) const; - + // fills a rect with a linear gradient, the caller should be // sure that the gradient is indeed vertical. The start point of // the gradient should be above the end point, or this function // will not draw anything. void FillRectVerticalGradient(BRect r, const BGradientLinear& gradient) const; - + // fills a solid rect with color c, no blending, no clipping void FillRectNoClipping(const clipping_rect& r, const rgb_color& c) const; @@ -177,7 +169,7 @@ public: BRect FillRoundRect(const BRect& r, float xRadius, float yRadius, const BGradient& gradient) const; - + // ellipses void AlignEllipseRect(BRect* rect, bool filled) const; @@ -197,7 +189,7 @@ public: BRect FillArc(BPoint center, float xRadius, float yRadius, float angle, float span, const BGradient& gradient) const; - + // strings BRect DrawString(const char* utf8String, uint32 length, BPoint baseLine, @@ -310,7 +302,7 @@ private: void _MakeGradient(const BGradient& gradient, int32 colorCount, uint32* colors, int32 arrayOffset, int32 arraySize) const; - + template void _MakeGradient(Array& array, const BGradient& gradient) const; @@ -332,7 +324,7 @@ private: template void _FillPathGradientConic(VertexSource& path, const BGradientConic& conic) const; - + mutable agg::rendering_buffer fBuffer; // AGG rendering and rasterization classes @@ -404,5 +396,3 @@ Painter::AlignAndClipRect(BRect rect) const #endif // PAINTER_H - -