// Copyright (C) 1996 Keith Whitwell. // This file may only be copied under the terms of the GNU Library General // Public License - see the file COPYING in the lib3d distribution. #include PointerArray *Device::children = 0; Exemplar Device::exemplar; Device::Device( Exemplar, uint capabilities ) : active(false), frameBuf(0), capabilities(capabilities) { } Device::Device() : active(false), frameBuf(0), pixelSize(1) { } Device::Device( uint w, uint h, uint ) : active(false), frameBuf(0), pixelSize(1) // meaningless default, must be overriden. { setSize(w, h); } void Device::setSize( uint w, uint h ) { width = ((w*pixelSize)&~0x03)/pixelSize; oldxmax = xmax = width; height = oldymax = ymax = h; xmin = 0; ymin = 0; oldxmin = 0; oldymin = 0; rowSize = width * pixelSize; } Device::~Device() { } Device * Device::create( uint width, uint height, uint min_depth, uint flags ) { if (!children) return 0; const char *deviceString; PointerArray &c = *children; c.sort( &Device::compare ); if ((deviceString = getenv("R_DEVICE")) != 0) { int i = c.getNr(); while (i--) { if (strcmp(deviceString, c[i]->getName()) == 0) { if ((c[i]->capabilities & flags) != flags) continue; ::debug() << "Trying device: " << c[i]->getName() << endlog; Device *dev = c[i]->clone(width,height,min_depth); if (dev && dev->isGood() && dev->initialize()) { dev->active = true; return dev; } delete dev; } } } int i = c.getNr(); while (i--) { if ((c[i]->capabilities & flags) != flags) continue; ::debug() << "Trying device: " << c[i]->getName() << endlog; Device *dev = c[i]->clone(width,height,min_depth); if (dev && dev->isGood() && dev->initialize()) { dev->active = true; return dev; } delete dev; } return 0; } int Device::compare( const Device **a, const Device **b ) { return (*a)->estimateSpeed() - (*b)->estimateSpeed(); } void Device::registerChildClass( Device *exemplar ) { if (children == 0) children = new PointerArray(1); children->nextFree() = exemplar; } void Device::clearBuffer( uint background ) { // This approach is reasonable for back buffers which are in // off-card ram. If your backbuffer is on the video card, this // approach won't be efficient, and you will probably want to use // some on-card acclerated function to clear the back buffer. // If you don't have access to such a function, you may find that // you get better performance with an off-card back buffer. This // is the reason why FlipDgaDevice is slower than XShmDevice in // lib3d-0.1.5, but BlitDgaDevice is faster. if_debug { debug() << "Cleaning x:"<> 2; asm("cld"); do { asm ("rep\n\t" "stosl" : /* no output registers */ : "c" (wid), "a" (background), "D" (fb) : "%ecx", "%edi" ); fb += rowSize; } while (--i); #else // I know that linux *has* an inline ARCH_MEMSET, but how do I // get at it? do { memset( fb, background, wid ); fb += rowSize; } while (--i); #endif } oldxmin = xmin; oldxmax = xmax; oldymin = ymin; oldymax = ymax; xmin = width; xmax = 0; ymin = height; ymax = 0; } bool Device::requestResize( uint &, uint & ) { return false; } void Device::notifyResize() { abort(); // If this is called, something's wrong. } void Device::notifyExpose(uint, uint, uint, uint) { } void Device::processPendingEvents() { } ostream & Device::print( ostream &out ) const { return Debuggable::print(out) << "\n\twidth:"<