mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added a read/write lock to the glyph cache. OpenGL shader fix.
This commit is contained in:
parent
2c0902833d
commit
5e795134fc
2 changed files with 73 additions and 56 deletions
|
|
@ -140,7 +140,6 @@ class GlyphCache : private DeletedAtShutdown
|
|||
{
|
||||
public:
|
||||
GlyphCache()
|
||||
: accessCounter (0), hits (0), misses (0)
|
||||
{
|
||||
addNewGlyphSlots (120);
|
||||
}
|
||||
|
|
@ -163,23 +162,70 @@ public:
|
|||
//==============================================================================
|
||||
void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, float x, float y)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
++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;)
|
||||
{
|
||||
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;
|
||||
glyph->lastAccessCount = accessCounter;
|
||||
glyph->draw (target, x, y);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (glyph == nullptr)
|
||||
{
|
||||
++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();
|
||||
}
|
||||
|
||||
jassert (glyph != nullptr);
|
||||
glyph->generate (font, glyphNumber);
|
||||
}
|
||||
|
||||
glyph->lastAccessCount = accessCounter.value;
|
||||
glyph->draw (target, x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class OwnedArray <CachedGlyphType>;
|
||||
OwnedArray <CachedGlyphType> glyphs;
|
||||
Atomic<int> accessCounter, hits, misses;
|
||||
ReadWriteLock lock;
|
||||
|
||||
void addNewGlyphSlots (int num)
|
||||
{
|
||||
while (--num >= 0)
|
||||
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)
|
||||
{
|
||||
|
|
@ -188,31 +234,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (hits + ++misses > glyphs.size() * 16)
|
||||
{
|
||||
if (misses * 2 > hits)
|
||||
addNewGlyphSlots (32);
|
||||
|
||||
hits = misses = 0;
|
||||
oldest = glyphs.getLast();
|
||||
}
|
||||
|
||||
jassert (oldest != nullptr);
|
||||
oldest->lastAccessCount = accessCounter;
|
||||
oldest->generate (font, glyphNumber);
|
||||
oldest->draw (target, x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class OwnedArray <CachedGlyphType>;
|
||||
OwnedArray <CachedGlyphType> glyphs;
|
||||
int accessCounter, hits, misses;
|
||||
CriticalSection lock;
|
||||
|
||||
void addNewGlyphSlots (int num)
|
||||
{
|
||||
while (--num >= 0)
|
||||
glyphs.add (new CachedGlyphType());
|
||||
return oldest;
|
||||
}
|
||||
|
||||
static GlyphCache*& getSingletonPointer() noexcept
|
||||
|
|
|
|||
|
|
@ -206,12 +206,7 @@ private:
|
|||
class ShaderPrograms : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
ShaderPrograms()
|
||||
: areShadersSupported (OpenGLShaderProgram::getLanguageVersion() >= 1.199)
|
||||
{
|
||||
}
|
||||
|
||||
const bool areShadersSupported;
|
||||
ShaderPrograms() {}
|
||||
|
||||
typedef ReferenceCountedObjectPtr<ShaderPrograms> Ptr;
|
||||
|
||||
|
|
@ -341,7 +336,7 @@ public:
|
|||
#define JUCE_MATRIX_TIMES_FRAGCOORD "(vec2 (matrix[0], matrix[3]) * gl_FragCoord.x" \
|
||||
" + vec2 (matrix[1], matrix[4]) * gl_FragCoord.y " \
|
||||
" + 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
|
||||
{
|
||||
|
|
@ -391,6 +386,8 @@ public:
|
|||
|
||||
#define JUCE_DECLARE_LINEAR_UNIFORMS "uniform sampler2D gradientTexture;" \
|
||||
"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
|
||||
{
|
||||
|
|
@ -399,7 +396,7 @@ public:
|
|||
JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length
|
||||
"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 ";"
|
||||
"}"),
|
||||
gradientParams (program)
|
||||
|
|
@ -416,7 +413,7 @@ public:
|
|||
JUCE_DECLARE_MASK_UNIFORMS
|
||||
"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 ";"
|
||||
"}"),
|
||||
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
|
||||
"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 ";"
|
||||
"}"),
|
||||
gradientParams (program)
|
||||
|
|
@ -451,7 +448,7 @@ public:
|
|||
JUCE_DECLARE_MASK_UNIFORMS
|
||||
"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 ";"
|
||||
"}"),
|
||||
gradientParams (program),
|
||||
|
|
@ -511,7 +508,7 @@ public:
|
|||
"void main()"
|
||||
"{"
|
||||
"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)
|
||||
{}
|
||||
|
|
@ -528,7 +525,7 @@ public:
|
|||
"void main()"
|
||||
"{"
|
||||
"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),
|
||||
maskParams (program)
|
||||
|
|
@ -546,7 +543,7 @@ public:
|
|||
"void main()"
|
||||
"{"
|
||||
"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)
|
||||
{}
|
||||
|
|
@ -563,7 +560,7 @@ public:
|
|||
"void main()"
|
||||
"{"
|
||||
"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),
|
||||
maskParams (program)
|
||||
|
|
@ -581,7 +578,7 @@ public:
|
|||
"void main()"
|
||||
"{"
|
||||
"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)
|
||||
{}
|
||||
|
|
@ -1204,7 +1201,7 @@ struct StateHelpers
|
|||
struct CurrentShader
|
||||
{
|
||||
CurrentShader() noexcept
|
||||
: canUseShaders (false), activeShader (nullptr)
|
||||
: canUseShaders (OpenGLShaderProgram::getLanguageVersion() >= 1.199), activeShader (nullptr)
|
||||
{
|
||||
OpenGLContext* context = OpenGLContext::getCurrentContext();
|
||||
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");
|
||||
programs = dynamic_cast <ShaderPrograms*> (context->properties [programValueID].getObject());
|
||||
|
||||
if (programs == nullptr)
|
||||
if (programs == nullptr && canUseShaders)
|
||||
{
|
||||
programs = new ShaderPrograms();
|
||||
context->properties.set (programValueID, var (programs));
|
||||
}
|
||||
|
||||
canUseShaders = programs->areShadersSupported;
|
||||
}
|
||||
|
||||
void setShader (const Rectangle<int>& bounds, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader)
|
||||
|
|
@ -2417,7 +2412,7 @@ public:
|
|||
state.activeTextures.bindTexture (other.mask.getTextureID());
|
||||
|
||||
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
|
||||
.setMatrix (AffineTransform::translation ((float) other.maskArea.getX(), (float) other.maskArea.getY()),
|
||||
other.maskArea.getWidth(), other.maskArea.getHeight(), 1.0f, 1.0f,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue