* 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
This commit is contained in:
Axel Dörfler 2011-09-29 23:58:34 +00:00
parent 7e701a612a
commit b6284c7f8a
4 changed files with 95 additions and 97 deletions

View File

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

View File

@ -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 <bpmagic@columbus.rr.com>
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
*/
#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 */

View File

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

View File

@ -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 <Rect.h>
// 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<class Array>
void _MakeGradient(Array& array,
const BGradient& gradient) const;
@ -332,7 +324,7 @@ private:
template<class VertexSource>
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