diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llcubemaparray.cpp | 8 | ||||
| -rw-r--r-- | indra/llrender/llcubemaparray.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llfontbitmapcache.cpp | 4 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 25 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 3 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 22 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.cpp | 6 | ||||
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.h | 5 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.h | 1 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 3 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 22 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 12 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.h | 3 | 
14 files changed, 95 insertions, 23 deletions
| diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 4f5e13765a..d0a97dc2c6 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -109,7 +109,7 @@ LLCubeMapArray::~LLCubeMapArray()  {  } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr)  {      U32 texname = 0;      mWidth = resolution; @@ -127,7 +127,11 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us      bind(0);      free_cur_tex_image(); -    U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F; +    U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F; +    if (!hdr) +    { +        format = components == 4 ? GL_RGBA8 : GL_RGB8; +    }      U32 mip = 0;      U32 mip_resolution = resolution;      while (mip_resolution >= 1) diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index 675aaaf07c..bfc72a321d 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -52,7 +52,7 @@ public:      // components - number of components per pixel      // count - number of cube maps in the array      // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used -    void allocate(U32 res, U32 components, U32 count, bool use_mips = true); +    void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true);      void bind(S32 stage);      void unbind(); diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index ee9cfd0719..83f5d31186 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp              mBitmapHeight = image_height;              S32 num_components = getNumComponents(bitmap_type); -            mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); +            mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));              bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1;              LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num); @@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp              }              // Make corresponding GL image. -            mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false)); +            mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false));              LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);              // Start at beginning of the new image. diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 6128e03fa7..38dc23d1dc 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -552,7 +552,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l          return NULL;      llassert(!mIsFallback); -    fontp->renderGlyph(requested_glyph_type, glyph_index); +    fontp->renderGlyph(requested_glyph_type, glyph_index, wch);      EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;      switch (fontp->mFTFace->glyph->bitmap.pixel_mode) @@ -697,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const      }  } -void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const +void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const  {      if (mFTFace == NULL)          return; @@ -712,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co      FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);      if (FT_Err_Ok != error)      { +        if (error == FT_Err_Out_Of_Memory) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL; +        } +          std::string message = llformat( -            "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", -            error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); +            "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d", +            error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags);          LL_WARNS_ONCE() << message << LL_ENDL;          error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); +        if (FT_Err_Invalid_Outline == error +            || FT_Err_Invalid_Composite == error +            || (FT_Err_Ok != error && LLStringOps::isEmoji(wch))) +        { +            glyph_index = FT_Get_Char_Index(mFTFace, '?'); +            // if '?' is not present, potentially can use last index, that's supposed to be null glyph +            if (glyph_index > 0) +            { +                error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); +            } +        }          llassert_always_msg(FT_Err_Ok == error, message.c_str());      } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index eba89f5def..a2d925c5f6 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -148,6 +148,7 @@ public:      void setStyle(U8 style);      U8 getStyle() const; +    S32 getAddedGlyphs() const { return mAddGlyphCount; }  private:      void resetBitmapCache(); @@ -156,7 +157,7 @@ private:      bool hasGlyph(llwchar wch) const;       // Has a glyph for this character      LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const;        // Add a new character to the font if necessary      LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) -    void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const; +    void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const;      void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;      std::string mName; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4c9a062246..4037c036e5 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -58,6 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f;  F32 LLFontGL::sHorizDPI = 96.f;  F32 LLFontGL::sScaleX = 1.f;  F32 LLFontGL::sScaleY = 1.f; +S32 LLFontGL::sResolutionGeneration = 0;  bool LLFontGL::sDisplayFont = true ;  std::string LLFontGL::sAppDir; @@ -109,6 +110,11 @@ S32 LLFontGL::getNumFaces(const std::string& filename)      return mFontFreetype->getNumFaces(filename);  } +S32 LLFontGL::getKnownGlyphCount() const +{ +    return mFontFreetype ? mFontFreetype->getAddedGlyphs() : 0; +} +  S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,      ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const  { @@ -249,6 +255,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); +    // This looks wrong, value is dynamic. +    // LLFontBitmapCache::nextOpenPos can alter these values when +    // new characters get added to cache, which affects whole string. +    // Todo: Perhaps value should update after symbols were added?      F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();      F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); @@ -270,6 +280,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      const LLFontGlyphInfo* next_glyph = NULL; +    // string can have more than one glyph per char (ex: bold or shadow), +    // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol. +    // See drawGlyph. +    // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars.      static constexpr S32 GLYPH_BATCH_SIZE = 30;      static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];      static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; @@ -282,6 +296,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);      S32 glyph_count = 0; +    llwchar last_char = wstr[begin_offset];      for (i = begin_offset; i < begin_offset + length; i++)      {          llwchar wch = wstr[i]; @@ -299,7 +314,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          }          // Per-glyph bitmap texture.          std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry; -        if (next_bitmap_entry != bitmap_entry) +        if (next_bitmap_entry != bitmap_entry || last_char != wch)          {              // Actually draw the queued glyphs before switching their texture;              // otherwise the queued glyphs will be taken from wrong textures. @@ -316,6 +331,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons              bitmap_entry = next_bitmap_entry;              LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);              gGL.getTexUnit(0)->bind(font_image); + +            // For some reason it's not enough to compare by bitmap_entry. +            // Issue hits emojis, japenese and chinese glyphs, only on first run. +            // Todo: figure it out, there might be a bug with raw image data. +            last_char = wch;          }          if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 4bb6c55c65..73efc6b1eb 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -90,6 +90,7 @@ public:      bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);      S32 getNumFaces(const std::string& filename); +    S32 getKnownGlyphCount() const;      S32 render(const LLWString &text, S32 begin_offset,                  const LLRect& rect, @@ -224,6 +225,7 @@ public:      static F32 sHorizDPI;      static F32 sScaleX;      static F32 sScaleY; +    static S32 sResolutionGeneration;      static bool sDisplayFont ;      static std::string sAppDir;         // For loading fonts diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index 5bd1ca5eed..b53a841a87 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -146,7 +146,9 @@ S32 LLFontVertexBuffer::render(               || mLastScaleY != LLFontGL::sScaleY               || mLastVertDPI != LLFontGL::sVertDPI               || mLastHorizDPI != LLFontGL::sHorizDPI -             || mLastOrigin != LLFontGL::sCurOrigin) +             || mLastOrigin != LLFontGL::sCurOrigin +             || mLastResGeneration != LLFontGL::sResolutionGeneration +             || mLastFontGlyphCount != fontp->getKnownGlyphCount())      {          genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,              style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); @@ -201,6 +203,8 @@ void LLFontVertexBuffer::genBuffers(      mLastVertDPI = LLFontGL::sVertDPI;      mLastHorizDPI = LLFontGL::sHorizDPI;      mLastOrigin = LLFontGL::sCurOrigin; +    mLastResGeneration = LLFontGL::sResolutionGeneration; +    mLastFontGlyphCount = fontp->getKnownGlyphCount();      if (right_x)      { diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index af195dfff9..d5e1280dbf 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -117,8 +117,13 @@ private:      F32 mLastScaleY = 1.f;      F32 mLastVertDPI = 0.f;      F32 mLastHorizDPI = 0.f; +    S32 mLastResGeneration = 0;      LLCoordGL mLastOrigin; +    // Adding new characters to bitmap cache can alter value from getBitmapWidth(); +    // which alters whole string. So rerender when new characters were added to cache. +    S32 mLastFontGlyphCount = 0; +      static bool sEnableBufferCollection;  }; diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 58c456f134..873ab0cff5 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -59,6 +59,7 @@ public:      bool attachNothing = false;      bool hasHeroProbes = false;      bool isPBRTerrain = false; +    bool hasTonemap = false;  };  // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 3858811a50..3f8903ca09 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -330,6 +330,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)      case GL_RGB:                                    return 24;      case GL_SRGB:                                   return 24;      case GL_RGB8:                                   return 24; +    case GL_R11F_G11F_B10F:                         return 32;      case GL_RGBA:                                   return 32;      case GL_RGBA8:                                  return 32;      case GL_RGB10_A2:                               return 32; @@ -1773,7 +1774,7 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)      ref();      LL::WorkQueue::postMaybe(          mMainQueue, -        [=]() +        [=, this]()          {              LL_PROFILE_ZONE_NAMED("cglt - delete callback");              syncTexName(new_tex_name); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d53850f74..1dc87a66ce 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -737,9 +737,8 @@ void LLLightState::setPosition(const LLVector4& position)      ++gGL.mLightHash;      mPosition = position;      //transform position by current modelview matrix -    glm::vec4 pos(glm::make_vec4(position.mV)); -    const glm::mat4& mat = gGL.getModelviewMatrix(); -    pos = mat * pos; +    glm::vec4 pos(position); +    pos = gGL.getModelviewMatrix() * pos;      mPosition.set(glm::value_ptr(pos));  } @@ -794,7 +793,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)      ++gGL.mLightHash;      //transform direction by current modelview matrix -    glm::vec3 dir(glm::make_vec3(direction.mV)); +    glm::vec3 dir(direction);      const glm::mat3 mat(gGL.getModelviewMatrix());      dir = mat * dir; @@ -2088,12 +2087,14 @@ void set_last_projection(const glm::mat4& mat)  glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)  { -    //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; -    //return glm::vec3( -    //    (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, -    //    (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, -    //    (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w -    //); +#if 1 // SIMD path results in strange crashes. Fall back to scalar for now. +    const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; +    return glm::vec3( +       (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, +       (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, +       (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w +    ); +#else      LLVector4a x, y, z, s, t, p, q;      x.splat(vec.x); @@ -2123,4 +2124,5 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)      res.setAdd(x, z);      res.div(q);      return glm::make_vec3(res.getF32ptr()); +#endif  } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0885740934..4807c12226 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)          }      } +    if (features->hasTonemap) +    { +        if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl")) +        { +            return false; +        } +    } +      // NOTE order of shader object attaching is VERY IMPORTANT!!!      if (features->hasAtmospherics)      { @@ -466,6 +474,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev      if (filename.empty())      { +        LL_WARNS("ShaderLoading") << "tried loading empty filename" << LL_ENDL;          return 0;      } @@ -923,6 +932,8 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev          }          LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;      } + +    LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL;      return ret;  } @@ -1389,6 +1400,7 @@ void LLShaderMgr::initAttribsAndUniforms()      mReservedUniforms.push_back("screenTex");      mReservedUniforms.push_back("screenDepth");      mReservedUniforms.push_back("refTex"); +    mReservedUniforms.push_back("exclusionTex");      mReservedUniforms.push_back("eyeVec");      mReservedUniforms.push_back("time");      mReservedUniforms.push_back("waveDir1"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 34bd73a42e..46788841a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -36,6 +36,8 @@ public:      LLShaderMgr();      virtual ~LLShaderMgr(); +    // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this. +    // Always document what the actual shader uniform is next to the shader uniform in this struct.      // clang-format off      typedef enum      {                                       // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms() @@ -234,6 +236,7 @@ public:          WATER_SCREENTEX,                    //  "screenTex"          WATER_SCREENDEPTH,                  //  "screenDepth"          WATER_REFTEX,                       //  "refTex" +        WATER_EXCLUSIONTEX,                 //  "exclusionTex"          WATER_EYEVEC,                       //  "eyeVec"          WATER_TIME,                         //  "time"          WATER_WAVE_DIR1,                    //  "waveDir1" | 
