/** * Get the blitter factory with the given name. * @param name the blitter factory to select. * @return The blitter factory, or nullptr when there isn't one with the wanted name. */ static BlitterFactory *GetBlitterFactory(const char *name) { #if defined(DEDICATED) const char *default_blitter = "null"; #else const char *default_blitter = "8bpp-optimized"; #if defined(WITH_COCOA) /* Some people reported lack of fullscreen support in 8 bpp mode. * While we prefer 8 bpp since it's faster, we will still have to test for support. */ if (!QZ_CanDisplay8bpp()) { /* The main display can't go to 8 bpp fullscreen mode. * We will have to switch to 32 bpp by default. */ default_blitter = "32bpp-anim"; } #endif /* defined(WITH_COCOA) */ #endif /* defined(DEDICATED) */ if (GetBlitters().size() == 0) return nullptr; const char *bname = (StrEmpty(name)) ? default_blitter : name; Blitters::iterator it = GetBlitters().begin(); for (; it != GetBlitters().end(); it++) { BlitterFactory *b = (*it).second; if (strcasecmp(bname, b->name) == 0) { return b; } } return nullptr; }
/** * Find the requested blitter and return his class. * @param name the blitter to select. * @post Sets the blitter so GetCurrentBlitter() returns it too. */ static Blitter *SelectBlitter(const char *name) { #if defined(DEDICATED) const char *default_blitter = "null"; #else const char *default_blitter = "8bpp-optimized"; #if defined(WITH_COCOA) /* Some people reported lack of fullscreen support in 8 bpp mode. * While we prefer 8 bpp since it's faster, we will still have to test for support. */ if (!QZ_CanDisplay8bpp()) { /* The main display can't go to 8 bpp fullscreen mode. * We will have to switch to 32 bpp by default. */ default_blitter = "32bpp-anim"; } #endif /* defined(WITH_COCOA) */ #endif /* defined(DEDICATED) */ if (GetBlitters().size() == 0) return NULL; const char *bname = (StrEmpty(name)) ? default_blitter : name; Blitters::iterator it = GetBlitters().begin(); for (; it != GetBlitters().end(); it++) { BlitterFactoryBase *b = (*it).second; if (strcasecmp(bname, b->name) == 0) { Blitter *newb = b->CreateInstance(); delete *GetActiveBlitter(); *GetActiveBlitter() = newb; DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", bname); return newb; } } return NULL; }
virtual ~BlitterFactoryBase() { if (this->name == NULL) return; GetBlitters().erase(this->name); if (GetBlitters().empty()) delete &GetBlitters(); free((void *)this->name); }
virtual ~BlitterFactory() { GetBlitters().erase(this->name); if (GetBlitters().empty()) delete &GetBlitters(); free(this->name); free(this->description); }
virtual ~BlitterFactory() { GetBlitters().erase(this->name); //果然做了delete,肩getBlitters() if (GetBlitters().empty()) delete &GetBlitters(); //stredup得来的字符串,需要free free(this->name); free(this->description); }
/** * Fill a buffer with information about the blitters. * @param p The buffer to fill. * @param last The last element of the buffer. * @return p The location till where we filled the buffer. */ static char *GetBlittersInfo(char *p, const char *last) { p += seprintf(p, last, "List of blitters:\n"); Blitters::iterator it = GetBlitters().begin(); for (; it != GetBlitters().end(); it++) { BlitterFactory *b = (*it).second; p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription()); } p += seprintf(p, last, "\n"); return p; }
/** * Register a blitter internally, based on his name. * @param name the name of the blitter. * @note an assert() will be trigger if 2 blitters with the same name try to register. */ void RegisterBlitter(const char *name) { /* Don't register nameless Blitters */ if (name == NULL) return; this->name = strdup(name); std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this)); assert(P.second); }
/** * Construct the blitter, and register it. * @param name The name of the blitter. * @param description A longer description for the blitter. * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them. * @pre name != nullptr. * @pre description != nullptr. * @pre There is no blitter registered with this name. */ BlitterFactory(const char *name, const char *description, bool usable = true) : name(stredup(name)), description(stredup(description)) { if (usable) { /* * Only add when the blitter is usable. Do not bail out or * do more special things since the blitters are always * instantiated upon start anyhow and freed upon shutdown. */ std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this)); assert(P.second); } else { DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name); } }
/** * Construct the blitter, and register it. * @param name The name of the blitter. * @param description A longer description for the blitter. * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them. * @pre name != NULL. * @pre description != NULL. * @pre There is no blitter registered with this name. */ BlitterFactory(const char *name, const char *description, bool usable = true) : name(stredup(name)), description(stredup(description)) { //stredup,相当于malloc©str /*strdup()函数是c语言中常用的一种字符串拷贝库函数,一般和free()函数成对出现。 */ if (usable) { /* * Only add when the blitter is usable. Do not bail out or * do more special things since the blitters are always * instantiated upon start anyhow and freed upon shutdown. */ /*std::map的insert函数,返回结果有两个,iterator和bool,其中iterator应该是当前插入的对象的访问迭代器. bool,表示这一次插入是否成功. */ std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this)); assert(P.second); } else { DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name); } }