diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2019-11-12 15:40:14 +0000 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2019-11-12 15:40:14 +0000 |
commit | 38d8eaba3e6e17dd39c9e9904852c14c95179783 (patch) | |
tree | 0703ba92d765b6d324eefa0d6a0de8fc6910f8cd /indra/llrender | |
parent | 63f82fc44b721b0ec437845d41b5a2055a44be68 (diff) | |
parent | 78bdf57ad6610b34389226bf941ba736ca0c2225 (diff) |
merge
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 122 | ||||
-rw-r--r-- | indra/llrender/llfontfreetype.h | 9 | ||||
-rw-r--r-- | indra/llrender/llfontgl.cpp | 20 | ||||
-rw-r--r-- | indra/llrender/llfontgl.h | 4 | ||||
-rw-r--r-- | indra/llrender/llfontregistry.cpp | 107 | ||||
-rw-r--r-- | indra/llrender/llfontregistry.h | 4 | ||||
-rw-r--r-- | indra/llrender/llrender2dutils.cpp | 93 | ||||
-rw-r--r-- | indra/llrender/llrender2dutils.h | 45 | ||||
-rw-r--r-- | indra/llrender/lluiimage.cpp | 12 |
9 files changed, 284 insertions, 132 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index ab668dc192..c41730ebaa 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) { } #endif -BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n) { // Don't leak face objects. This is also needed to deal with // changed font file names. @@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v } int error; - #ifdef LL_WINDOWS - pFileStream = new llifstream(filename, std::ios::binary); - if (pFileStream->is_open()) - { - std::streampos beg = pFileStream->tellg(); - pFileStream->seekg(0, std::ios::end); - std::streampos end = pFileStream->tellg(); - std::size_t file_size = end - beg; - pFileStream->seekg(0, std::ios::beg); - - pFtStream = new LLFT_Stream(); - pFtStream->base = 0; - pFtStream->pos = 0; - pFtStream->size = file_size; - pFtStream->descriptor.pointer = pFileStream; - pFtStream->read = ft_read_cb; - pFtStream->close = ft_close_cb; - - FT_Open_Args args; - args.flags = FT_OPEN_STREAM; - args.stream = (FT_StreamRec*)pFtStream; - - error = FT_Open_Face(gFTLibrary, - &args, - 0, - &mFTFace); - } - else - { - delete pFileStream; - pFileStream = NULL; - return FALSE; - } + error = ftOpenFace(filename, face_n); #else error = FT_New_Face( gFTLibrary, filename.c_str(), @@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (error) { #ifdef LL_WINDOWS - pFileStream->close(); - delete pFileStream; - delete pFtStream; - pFileStream = NULL; - pFtStream = NULL; + clearFontStreams(); #endif return FALSE; } @@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v // Clean up freetype libs. FT_Done_Face(mFTFace); #ifdef LL_WINDOWS - pFileStream->close(); - delete pFileStream; - delete pFtStream; - pFileStream = NULL; - pFtStream = NULL; + clearFontStreams(); #endif mFTFace = NULL; return FALSE; @@ -285,18 +245,88 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD) { mStyle |= LLFontGL::BOLD; - mStyle &= ~LLFontGL::NORMAL; } if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC) { mStyle |= LLFontGL::ITALIC; - mStyle &= ~LLFontGL::NORMAL; } return TRUE; } +S32 LLFontFreetype::getNumFaces(const std::string& filename) +{ + if (mFTFace) + { + FT_Done_Face(mFTFace); + mFTFace = NULL; + } + + S32 num_faces = 1; + +#ifdef LL_WINDOWS + int error = ftOpenFace(filename, 0); + + if (error) + { + return 0; + } + else + { + num_faces = mFTFace->num_faces; + } + + FT_Done_Face(mFTFace); + clearFontStreams(); + mFTFace = NULL; +#endif + + return num_faces; +} + +#ifdef LL_WINDOWS +S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n) +{ + S32 error = -1; + pFileStream = new llifstream(filename, std::ios::binary); + if (pFileStream->is_open()) + { + std::streampos beg = pFileStream->tellg(); + pFileStream->seekg(0, std::ios::end); + std::streampos end = pFileStream->tellg(); + std::size_t file_size = end - beg; + pFileStream->seekg(0, std::ios::beg); + + pFtStream = new LLFT_Stream(); + pFtStream->base = 0; + pFtStream->pos = 0; + pFtStream->size = file_size; + pFtStream->descriptor.pointer = pFileStream; + pFtStream->read = ft_read_cb; + pFtStream->close = ft_close_cb; + + FT_Open_Args args; + args.flags = FT_OPEN_STREAM; + args.stream = (FT_StreamRec*)pFtStream; + error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace); + } + return error; +} + +void LLFontFreetype::clearFontStreams() +{ + if (pFileStream) + { + pFileStream->close(); + } + delete pFileStream; + delete pFtStream; + pFileStream = NULL; + pFtStream = NULL; +} +#endif + void LLFontFreetype::setFallbackFonts(const font_vector_t &font) { mFallbackFonts = font; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index aadebf5e70..1afe84e770 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -84,7 +84,14 @@ public: // is_fallback should be true for fallback fonts that aren't used // to render directly (Unicode backup, primarily) - BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0); + + S32 getNumFaces(const std::string& filename); + +#ifdef LL_WINDOWS + S32 ftOpenFace(const std::string& filename, S32 face_n); + void clearFontStreams(); +#endif typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 8cd18c5fa1..86a4c35e6d 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -89,14 +89,24 @@ void LLFontGL::destroyGL() mFontFreetype->destroyGL(); } -BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n) { if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL)) { mFontFreetype = new LLFontFreetype; } - return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); + return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n); +} + +S32 LLFontGL::getNumFaces(const std::string& filename) +{ + if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL)) + { + mFontFreetype = new LLFontFreetype; + } + + return mFontFreetype->getNumFaces(filename); } static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts"); @@ -860,10 +870,6 @@ void LLFontGL::destroyAllGL() U8 LLFontGL::getStyleFromString(const std::string &style) { S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } if (style.find("BOLD") != style.npos) { ret |= BOLD; @@ -883,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style) std::string LLFontGL::getStringFromStyle(U8 style) { std::string style_string; - if (style & NORMAL) + if (style == NORMAL) { style_string += "|NORMAL"; } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 7d0e53f60f..10891faed9 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -87,7 +87,9 @@ public: void destroyGL(); - BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); + BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0); + + S32 getNumFaces(const std::string& filename); S32 render(const LLWString &text, S32 begin_offset, const LLRect& rect, diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 3c829596ce..dbe71e2882 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -44,6 +44,8 @@ using std::map; bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc); bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node); +const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/"; + LLFontDescriptor::LLFontDescriptor(): mStyle(0) { @@ -61,6 +63,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name, } LLFontDescriptor::LLFontDescriptor(const std::string& name, + const std::string& size, + const U8 style, + const string_vec_t& file_names, + const string_vec_t& ft_collection_listections) : + LLFontDescriptor(name, size, style, file_names) +{ + mFontCollectionsList = ft_collection_listections; +} + +LLFontDescriptor::LLFontDescriptor(const std::string& name, const std::string& size, const U8 style): mName(name), @@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const if (removeSubString(new_name,"Italic")) new_style |= LLFontGL::ITALIC; - return LLFontDescriptor(new_name,new_size,new_style,getFileNames()); + return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList()); } LLFontRegistry::LLFontRegistry(bool create_gl_textures) @@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename) success = success || init_succ; } } + //if (success) // dump(); @@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc) { std::string font_file_name = child->getTextContents(); desc.getFileNames().push_back(font_file_name); + + if (child->hasAttribute("load_collection")) + { + BOOL col = FALSE; + child->getAttributeBOOL("load_collection", col); + if (col) + { + desc.getFontCollectionsList().push_back(font_file_name); + } + } } else if (child->hasName("os")) { @@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node) match_file_names.insert(match_file_names.begin(), desc.getFileNames().begin(), desc.getFileNames().end()); + + string_vec_t collections_list = match_desc->getFontCollectionsList(); + collections_list.insert(collections_list.begin(), + desc.getFontCollectionsList().begin(), + desc.getFontCollectionsList().end()); + LLFontDescriptor new_desc = *match_desc; new_desc.getFileNames() = match_file_names; + new_desc.getFontCollectionsList() = collections_list; registry->mFontMap.erase(*match_desc); registry->mFontMap[new_desc] = NULL; } @@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) // Build list of font names to look for. // Files specified for this font come first, followed by those from the default descriptor. string_vec_t file_names = match_desc->getFileNames(); + string_vec_t ft_collection_list = match_desc->getFontCollectionsList(); string_vec_t default_file_names; LLFontDescriptor default_desc("default",s_template_string,0); const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc); @@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) file_names.insert(file_names.end(), match_default_desc->getFileNames().begin(), match_default_desc->getFileNames().end()); + ft_collection_list.insert(ft_collection_list.end(), + match_default_desc->getFontCollectionsList().begin(), + match_default_desc->getFontCollectionsList().end()); } // Add ultimate fallback list - generated dynamically on linux, @@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) file_name_it != file_names.end(); ++file_name_it) { - LLFontGL *fontp = new LLFontGL; - std::string font_path = local_path + *file_name_it; + LLFontGL *fontp = NULL; + string_vec_t font_paths; + font_paths.push_back(local_path + *file_name_it); + font_paths.push_back(sys_path + *file_name_it); +#if LL_DARWIN + font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it); +#endif + + bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end()); // *HACK: Fallback fonts don't render, so we can use that to suppress // creation of OpenGL textures for test apps. JC BOOL is_fallback = !is_first_found || !mCreateGLTextures; F32 extra_scale = (is_fallback)?fallback_scale:1.0; - if (!fontp->loadFace(font_path, extra_scale * point_size, - LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) + F32 point_size_scale = extra_scale * point_size; + bool is_font_loaded = false; + for(string_vec_t::iterator font_paths_it = font_paths.begin(); + font_paths_it != font_paths.end(); + ++font_paths_it) { - font_path = sys_path + *file_name_it; - - if (!fontp->loadFace(font_path, extra_scale * point_size, - LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) + fontp = new LLFontGL; + S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1; + for (S32 i = 0; i < num_faces; i++) { - LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL; - delete fontp; - fontp = NULL; + if (fontp == NULL) + { + fontp = new LLFontGL; + } + if (fontp->loadFace(*font_paths_it, point_size_scale, + LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i)) + { + is_font_loaded = true; + if (is_first_found) + { + result = fontp; + is_first_found = false; + } + else + { + fontlist.push_back(fontp->mFontFreetype); + delete fontp; + fontp = NULL; + } + } + else + { + delete fontp; + fontp = NULL; + } } + if (is_font_loaded) break; } - - if(fontp) + if(!is_font_loaded) { - if (is_first_found) - { - result = fontp; - is_first_found = false; - } - else - { - fontlist.push_back(fontp->mFontFreetype); - delete fontp; - fontp = NULL; - } + LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL; + delete fontp; + fontp = NULL; } } diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 177eb6c8a5..e30c81c630 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -40,6 +40,7 @@ public: LLFontDescriptor(); LLFontDescriptor(const std::string& name, const std::string& size, const U8 style); LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names); + LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections); LLFontDescriptor normalize() const; bool operator<(const LLFontDescriptor& b) const; @@ -52,6 +53,8 @@ public: void setSize(const std::string& size) { mSize = size; } const std::vector<std::string>& getFileNames() const { return mFileNames; } std::vector<std::string>& getFileNames() { return mFileNames; } + const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; } + std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; } const U8 getStyle() const { return mStyle; } void setStyle(U8 style) { mStyle = style; } @@ -59,6 +62,7 @@ private: std::string mName; std::string mSize; string_vec_t mFileNames; + string_vec_t mFontCollectionsList; U8 mStyle; }; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 4e2ebfd51e..4eb0203245 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -46,8 +46,6 @@ // Globals // const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); -/*static*/ LLVector2 LLRender2D::sGLScaleFactor(1.f, 1.f); -/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL; // // Functions @@ -108,10 +106,11 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe top += LLFontGL::sCurOrigin.mY; gGL.loadUIIdentity(); - gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset, - llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset, - llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset, - llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset, + LLRender2D *r2d_inst = LLRender2D::getInstance(); + gl_rect_2d(llfloor((F32)left * r2d_inst->mGLScaleFactor.mV[VX]) - pixel_offset, + llfloor((F32)top * r2d_inst->mGLScaleFactor.mV[VY]) + pixel_offset, + llfloor((F32)right * r2d_inst->mGLScaleFactor.mV[VX]) + pixel_offset, + llfloor((F32)bottom * r2d_inst->mGLScaleFactor.mV[VY]) - pixel_offset, filled); gGL.popUIMatrix(); } @@ -800,7 +799,7 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL } gGL.end(); - LLRender2D::setLineWidth(1.f); + LLRender2D::getInstance()->setLineWidth(1.f); } void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) @@ -967,7 +966,7 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha) } else { //polygon stipple is deprecated, use "Checker" texture - LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker"); + LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker"); gGL.getTexUnit(0)->bind(img->getImage()); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); @@ -1567,25 +1566,26 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv } -// static -void LLRender2D::initClass(LLImageProviderInterface* image_provider, - const LLVector2* scale_factor) +LLRender2D::LLRender2D(LLImageProviderInterface* image_provider) { - sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; - sImageProvider = image_provider; + mGLScaleFactor = LLVector2(1.f, 1.f); + mImageProvider = image_provider; + if(mImageProvider) + { + mImageProvider->addOnRemovalCallback(resetProvider); + } } -// static -void LLRender2D::cleanupClass() +LLRender2D::~LLRender2D() { - if(sImageProvider) + if(mImageProvider) { - sImageProvider->cleanUp(); + mImageProvider->cleanUp(); + mImageProvider->deleteOnRemovalCallback(resetProvider); } } -//static void LLRender2D::translate(F32 x, F32 y, F32 z) { gGL.translateUI(x,y,z); @@ -1594,14 +1594,12 @@ void LLRender2D::translate(F32 x, F32 y, F32 z) LLFontGL::sCurDepth += z; } -//static void LLRender2D::pushMatrix() { gGL.pushUIMatrix(); LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth)); } -//static void LLRender2D::popMatrix() { gGL.popUIMatrix(); @@ -1610,7 +1608,6 @@ void LLRender2D::popMatrix() LLFontGL::sOriginStack.pop_back(); } -//static void LLRender2D::loadIdentity() { gGL.loadUIIdentity(); @@ -1619,25 +1616,22 @@ void LLRender2D::loadIdentity() LLFontGL::sCurDepth = 0.f; } -//static void LLRender2D::setScaleFactor(const LLVector2 &scale_factor) { - sGLScaleFactor = scale_factor; + mGLScaleFactor = scale_factor; } -//static void LLRender2D::setLineWidth(F32 width) { gGL.flush(); - glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); + glLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f)); } -//static LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) { - if (sImageProvider) + if (mImageProvider) { - return sImageProvider->getUIImageByID(image_id, priority); + return mImageProvider->getUIImageByID(image_id, priority); } else { @@ -1645,12 +1639,49 @@ LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 prio } } -//static LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority) { - if (!name.empty() && sImageProvider) - return sImageProvider->getUIImage(name, priority); + if (!name.empty() && mImageProvider) + return mImageProvider->getUIImage(name, priority); else return NULL; } +// static +void LLRender2D::resetProvider() +{ + if (LLRender2D::instanceExists) + { + LLRender2D::getInstance()->mImageProvider = NULL; + } +} + +// class LLImageProviderInterface + +LLImageProviderInterface::~LLImageProviderInterface() +{ + for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end();) + { + callback_list_t::iterator curiter = iter++; + (*curiter)(); + } +} + +void LLImageProviderInterface::addOnRemovalCallback(callback_t func) +{ + if (!func) + { + return; + } + mCallbackList.push_back(func); +} + +void LLImageProviderInterface::deleteOnRemovalCallback(callback_t func) +{ + callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), func); + if (iter != mCallbackList.end()) + { + mCallbackList.erase(iter); + } +} + diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index cce3b4ed51..70ab006fd6 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -121,39 +121,54 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL class LLImageProviderInterface; -class LLRender2D +class LLRender2D : public LLParamSingleton<LLRender2D> { + LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider); LOG_CLASS(LLRender2D); + ~LLRender2D(); public: - static void initClass(LLImageProviderInterface* image_provider, - const LLVector2* scale_factor); - static void cleanupClass(); + void pushMatrix(); + void popMatrix(); + void loadIdentity(); + void translate(F32 x, F32 y, F32 z = 0.0f); - static void pushMatrix(); - static void popMatrix(); - static void loadIdentity(); - static void translate(F32 x, F32 y, F32 z = 0.0f); + void setLineWidth(F32 width); + void setScaleFactor(const LLVector2& scale_factor); - static void setLineWidth(F32 width); - static void setScaleFactor(const LLVector2& scale_factor); + LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0); + LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0); - static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0); - static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0); + LLVector2 mGLScaleFactor; + +protected: + // since LLRender2D has no control of image provider's lifecycle + // we need a way to tell LLRender2D that provider died and + // LLRender2D needs to be updated. + static void resetProvider(); - static LLVector2 sGLScaleFactor; private: - static LLImageProviderInterface* sImageProvider; + LLImageProviderInterface* mImageProvider; }; class LLImageProviderInterface { protected: LLImageProviderInterface() {}; - virtual ~LLImageProviderInterface() {}; + virtual ~LLImageProviderInterface(); public: virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0; virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0; virtual void cleanUp() = 0; + + // to notify holders when pointer gets deleted + typedef void(*callback_t)(); + void addOnRemovalCallback(callback_t func); + void deleteOnRemovalCallback(callback_t func); + +private: + + typedef std::list< callback_t > callback_list_t; + callback_list_t mCallbackList; }; diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp index 5d8f92b2e6..c8337feabb 100644 --- a/indra/llrender/lluiimage.cpp +++ b/indra/llrender/lluiimage.cpp @@ -120,12 +120,12 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c } } - LLRender2D::pushMatrix(); + LLRender2D::getInstance()->pushMatrix(); { LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis); - LLRender2D::translate(rect_origin.mV[VX], - rect_origin.mV[VY], - rect_origin.mV[VZ]); + LLRender2D::getInstance()->translate(rect_origin.mV[VX], + rect_origin.mV[VY], + rect_origin.mV[VZ]); gGL.getTexUnit(0)->bind(getImage()); gGL.color4fv(color.mV); @@ -142,7 +142,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c rect.getWidth() * x_axis, rect.getHeight() * y_axis); - } LLRender2D::popMatrix(); + } LLRender2D::getInstance()->popMatrix(); } @@ -199,7 +199,7 @@ namespace LLInitParam return; } - LLUIImage* imagep = LLRender2D::getUIImage(name()); + LLUIImage* imagep = LLRender2D::getInstance()->getUIImage(name()); if (imagep) { updateValue(imagep); |