Browse Source

Added a read/write lock to the glyph cache. OpenGL shader fix.

tags/2021-05-28
jules 13 years ago
parent
commit
5e795134fc
2 changed files with 65 additions and 48 deletions
  1. +49
    -27
      modules/juce_graphics/native/juce_RenderingHelpers.h
  2. +16
    -21
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp

+ 49
- 27
modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -140,7 +140,6 @@ class GlyphCache : private DeletedAtShutdown
{ {
public: public:
GlyphCache() GlyphCache()
: accessCounter (0), hits (0), misses (0)
{ {
addNewGlyphSlots (120); addNewGlyphSlots (120);
} }
@@ -163,51 +162,55 @@ public:
//============================================================================== //==============================================================================
void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, float x, float y) void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, float x, float y)
{ {
const ScopedLock sl (lock);
++accessCounter; ++accessCounter;
int oldestCounter = std::numeric_limits<int>::max();
CachedGlyphType* oldest = nullptr;
CachedGlyphType* glyph = nullptr;
const ScopedReadLock srl (lock);
for (int i = glyphs.size(); --i >= 0;) for (int i = glyphs.size(); --i >= 0;)
{ {
CachedGlyphType* const glyph = glyphs.getUnchecked (i);
CachedGlyphType* const g = glyphs.getUnchecked (i);
if (glyph->glyph == glyphNumber && glyph->font == font)
if (g->glyph == glyphNumber && g->font == font)
{ {
glyph = g;
++hits; ++hits;
glyph->lastAccessCount = accessCounter;
glyph->draw (target, x, y);
return;
}
if (glyph->lastAccessCount <= oldestCounter)
{
oldestCounter = glyph->lastAccessCount;
oldest = glyph;
break;
} }
} }
if (hits + ++misses > glyphs.size() * 16)
if (glyph == nullptr)
{ {
if (misses * 2 > hits)
addNewGlyphSlots (32);
++misses;
const ScopedWriteLock swl (lock);
if (hits.value + misses.value > glyphs.size() * 16)
{
if (misses.value * 2 > hits.value)
addNewGlyphSlots (32);
hits.set (0);
misses.set (0);
glyph = glyphs.getLast();
}
else
{
glyph = findLeastRecentlyUsedGlyph();
}
hits = misses = 0;
oldest = glyphs.getLast();
jassert (glyph != nullptr);
glyph->generate (font, glyphNumber);
} }
jassert (oldest != nullptr);
oldest->lastAccessCount = accessCounter;
oldest->generate (font, glyphNumber);
oldest->draw (target, x, y);
glyph->lastAccessCount = accessCounter.value;
glyph->draw (target, x, y);
} }
private: private:
friend class OwnedArray <CachedGlyphType>; friend class OwnedArray <CachedGlyphType>;
OwnedArray <CachedGlyphType> glyphs; OwnedArray <CachedGlyphType> glyphs;
int accessCounter, hits, misses;
CriticalSection lock;
Atomic<int> accessCounter, hits, misses;
ReadWriteLock lock;
void addNewGlyphSlots (int num) void addNewGlyphSlots (int num)
{ {
@@ -215,6 +218,25 @@ private:
glyphs.add (new CachedGlyphType()); glyphs.add (new CachedGlyphType());
} }
CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept
{
CachedGlyphType* oldest = glyphs.getLast();
int oldestCounter = oldest->lastAccessCount;
for (int i = glyphs.size() - 1; --i >= 0;)
{
CachedGlyphType* const glyph = glyphs.getUnchecked(i);
if (glyph->lastAccessCount <= oldestCounter)
{
oldestCounter = glyph->lastAccessCount;
oldest = glyph;
}
}
return oldest;
}
static GlyphCache*& getSingletonPointer() noexcept static GlyphCache*& getSingletonPointer() noexcept
{ {
static GlyphCache* g = nullptr; static GlyphCache* g = nullptr;


+ 16
- 21
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -206,12 +206,7 @@ private:
class ShaderPrograms : public ReferenceCountedObject class ShaderPrograms : public ReferenceCountedObject
{ {
public: public:
ShaderPrograms()
: areShadersSupported (OpenGLShaderProgram::getLanguageVersion() >= 1.199)
{
}
const bool areShadersSupported;
ShaderPrograms() {}
typedef ReferenceCountedObjectPtr<ShaderPrograms> Ptr; typedef ReferenceCountedObjectPtr<ShaderPrograms> Ptr;
@@ -341,7 +336,7 @@ public:
#define JUCE_MATRIX_TIMES_FRAGCOORD "(vec2 (matrix[0], matrix[3]) * gl_FragCoord.x" \ #define JUCE_MATRIX_TIMES_FRAGCOORD "(vec2 (matrix[0], matrix[3]) * gl_FragCoord.x" \
" + vec2 (matrix[1], matrix[4]) * gl_FragCoord.y " \ " + vec2 (matrix[1], matrix[4]) * gl_FragCoord.y " \
" + vec2 (matrix[2], matrix[5]))" " + vec2 (matrix[2], matrix[5]))"
#define JUCE_GET_TEXTURE_COLOUR "(gl_Color.w * texture2D (gradientTexture, vec2 (gradientPos, 0.5)))"
#define JUCE_GET_TEXTURE_COLOUR "(gl_Color.a * texture2D (gradientTexture, vec2 (gradientPos, 0.5)))"
struct RadialGradientProgram : public ShaderBase struct RadialGradientProgram : public ShaderBase
{ {
@@ -391,6 +386,8 @@ public:
#define JUCE_DECLARE_LINEAR_UNIFORMS "uniform sampler2D gradientTexture;" \ #define JUCE_DECLARE_LINEAR_UNIFORMS "uniform sampler2D gradientTexture;" \
"uniform vec4 gradientInfo;" "uniform vec4 gradientInfo;"
#define JUCE_CALC_LINEAR_GRAD_POS1 "float gradientPos = (gl_FragCoord.y - (gradientInfo.y + (gradientInfo.z * (gl_FragCoord.x - gradientInfo.x)))) / gradientInfo.w;"
#define JUCE_CALC_LINEAR_GRAD_POS2 "float gradientPos = (gl_FragCoord.x - (gradientInfo.x + (gradientInfo.z * (gl_FragCoord.y - gradientInfo.y)))) / gradientInfo.w;"
struct LinearGradient1Program : public ShaderBase struct LinearGradient1Program : public ShaderBase
{ {
@@ -399,7 +396,7 @@ public:
JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length
"void main()" "void main()"
"{" "{"
"float gradientPos = (gl_FragCoord.y - (gradientInfo.y + (gradientInfo.z * (gl_FragCoord.x - gradientInfo.x)))) / gradientInfo.w;"
JUCE_CALC_LINEAR_GRAD_POS1
"gl_FragColor = " JUCE_GET_TEXTURE_COLOUR ";" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR ";"
"}"), "}"),
gradientParams (program) gradientParams (program)
@@ -416,7 +413,7 @@ public:
JUCE_DECLARE_MASK_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS
"void main()" "void main()"
"{" "{"
"float gradientPos = (gl_FragCoord.y - (gradientInfo.y + (gradientInfo.z * (gl_FragCoord.x - gradientInfo.x)))) / gradientInfo.w;"
JUCE_CALC_LINEAR_GRAD_POS1
"gl_FragColor = " JUCE_GET_TEXTURE_COLOUR " * " JUCE_GET_MASK_ALPHA ";" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR " * " JUCE_GET_MASK_ALPHA ";"
"}"), "}"),
gradientParams (program), gradientParams (program),
@@ -434,7 +431,7 @@ public:
JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length
"void main()" "void main()"
"{" "{"
"float gradientPos = (gl_FragCoord.x - (gradientInfo.x + (gradientInfo.z * (gl_FragCoord.y - gradientInfo.y)))) / gradientInfo.w;"
JUCE_CALC_LINEAR_GRAD_POS2
"gl_FragColor = " JUCE_GET_TEXTURE_COLOUR ";" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR ";"
"}"), "}"),
gradientParams (program) gradientParams (program)
@@ -451,7 +448,7 @@ public:
JUCE_DECLARE_MASK_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS
"void main()" "void main()"
"{" "{"
"float gradientPos = (gl_FragCoord.x - (gradientInfo.x + (gradientInfo.z * (gl_FragCoord.y - gradientInfo.y)))) / gradientInfo.w;"
JUCE_CALC_LINEAR_GRAD_POS2
"gl_FragColor = " JUCE_GET_TEXTURE_COLOUR " * " JUCE_GET_MASK_ALPHA ";" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR " * " JUCE_GET_MASK_ALPHA ";"
"}"), "}"),
gradientParams (program), gradientParams (program),
@@ -511,7 +508,7 @@ public:
"void main()" "void main()"
"{" "{"
"vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" "vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);"
"gl_FragColor = gl_Color.w * " JUCE_GET_IMAGE_PIXEL ";"
"gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";"
"}"), "}"),
imageParams (program) imageParams (program)
{} {}
@@ -528,7 +525,7 @@ public:
"void main()" "void main()"
"{" "{"
"vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" "vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);"
"gl_FragColor = gl_Color.w * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";"
"gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";"
"}"), "}"),
imageParams (program), imageParams (program),
maskParams (program) maskParams (program)
@@ -546,7 +543,7 @@ public:
"void main()" "void main()"
"{" "{"
"vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);"
"gl_FragColor = gl_Color.w * " JUCE_GET_IMAGE_PIXEL ";"
"gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";"
"}"), "}"),
imageParams (program) imageParams (program)
{} {}
@@ -563,7 +560,7 @@ public:
"void main()" "void main()"
"{" "{"
"vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);"
"gl_FragColor = gl_Color.w * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";"
"gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";"
"}"), "}"),
imageParams (program), imageParams (program),
maskParams (program) maskParams (program)
@@ -581,7 +578,7 @@ public:
"void main()" "void main()"
"{" "{"
"vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);"
"gl_FragColor = " JUCE_GET_IMAGE_PIXEL ";"
"gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";"
"}"), "}"),
imageParams (program) imageParams (program)
{} {}
@@ -1204,7 +1201,7 @@ struct StateHelpers
struct CurrentShader struct CurrentShader
{ {
CurrentShader() noexcept CurrentShader() noexcept
: canUseShaders (false), activeShader (nullptr)
: canUseShaders (OpenGLShaderProgram::getLanguageVersion() >= 1.199), activeShader (nullptr)
{ {
OpenGLContext* context = OpenGLContext::getCurrentContext(); OpenGLContext* context = OpenGLContext::getCurrentContext();
jassert (context != nullptr); // You can only use this class when you have an active GL context! jassert (context != nullptr); // You can only use this class when you have an active GL context!
@@ -1212,13 +1209,11 @@ struct StateHelpers
const Identifier programValueID ("GraphicsContextPrograms"); const Identifier programValueID ("GraphicsContextPrograms");
programs = dynamic_cast <ShaderPrograms*> (context->properties [programValueID].getObject()); programs = dynamic_cast <ShaderPrograms*> (context->properties [programValueID].getObject());
if (programs == nullptr)
if (programs == nullptr && canUseShaders)
{ {
programs = new ShaderPrograms(); programs = new ShaderPrograms();
context->properties.set (programValueID, var (programs)); context->properties.set (programValueID, var (programs));
} }
canUseShaders = programs->areShadersSupported;
} }
void setShader (const Rectangle<int>& bounds, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader) void setShader (const Rectangle<int>& bounds, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader)
@@ -2417,7 +2412,7 @@ public:
state.activeTextures.bindTexture (other.mask.getTextureID()); state.activeTextures.bindTexture (other.mask.getTextureID());
state.currentShader.setShader (maskArea, state.shaderQuadQueue, state.currentShader.programs->copyTexture); state.currentShader.setShader (maskArea, state.shaderQuadQueue, state.currentShader.programs->copyTexture);
state.currentShader.programs->maskTexture.imageParams.imageTexture.set (0);
state.currentShader.programs->copyTexture.imageParams.imageTexture.set (0);
state.currentShader.programs->copyTexture.imageParams state.currentShader.programs->copyTexture.imageParams
.setMatrix (AffineTransform::translation ((float) other.maskArea.getX(), (float) other.maskArea.getY()), .setMatrix (AffineTransform::translation ((float) other.maskArea.getX(), (float) other.maskArea.getY()),
other.maskArea.getWidth(), other.maskArea.getHeight(), 1.0f, 1.0f, other.maskArea.getWidth(), other.maskArea.getHeight(), 1.0f, 1.0f,


Loading…
Cancel
Save