Browse Source

OpenGL renderer optimisations.

tags/2021-05-28
jules 14 years ago
parent
commit
c38916b675
13 changed files with 135 additions and 184 deletions
  1. +10
    -20
      modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  2. +1
    -1
      modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h
  3. +1
    -1
      modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp
  4. +1
    -1
      modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h
  5. +2
    -42
      modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  6. +1
    -1
      modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h
  7. +42
    -0
      modules/juce_graphics/native/juce_RenderingHelpers.h
  8. +1
    -1
      modules/juce_graphics/native/juce_android_GraphicsContext.cpp
  9. +1
    -1
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h
  10. +1
    -1
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  11. +1
    -1
      modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp
  12. +72
    -113
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  13. +1
    -1
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h

+ 10
- 20
modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -291,20 +291,15 @@ StringArray MidiOutput::getDevices()
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef dest = MIDIGetDestination (i);
String name;
if (dest != 0)
{
String name (CoreMidiHelpers::getConnectedEndpointName (dest));
name = CoreMidiHelpers::getConnectedEndpointName (dest);
if (name.isEmpty())
name = "<error>";
if (name.isEmpty())
name = "<error>";
s.add (name);
}
else
{
s.add ("<error>");
}
s.add (name);
}
return s;
@@ -413,20 +408,15 @@ StringArray MidiInput::getDevices()
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef source = MIDIGetSource (i);
String name;
if (source != 0)
{
String name (CoreMidiHelpers::getConnectedEndpointName (source));
name = CoreMidiHelpers::getConnectedEndpointName (source);
if (name.isEmpty())
name = "<error>";
if (name.isEmpty())
name = "<error>";
s.add (name);
}
else
{
s.add ("<error>");
}
s.add (name);
}
return s;


+ 1
- 1
modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h View File

@@ -101,7 +101,7 @@ public:
virtual void drawHorizontalLine (int y, float left, float right) = 0;
virtual void setFont (const Font& newFont) = 0;
virtual Font getFont() = 0;
virtual const Font& getFont() = 0;
virtual void drawGlyph (int glyphNumber, const AffineTransform& transform) = 0;
virtual bool drawTextLayout (const AttributedString&, const Rectangle<float>&) { return false; }
};


+ 1
- 1
modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp View File

@@ -530,7 +530,7 @@ void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont)
stateStack.getLast()->font = newFont;
}
Font LowLevelGraphicsPostScriptRenderer::getFont()
const Font& LowLevelGraphicsPostScriptRenderer::getFont()
{
return stateStack.getLast()->font;
}


+ 1
- 1
modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h View File

@@ -85,7 +85,7 @@ public:
void drawHorizontalLine (int x, float top, float bottom);
//==============================================================================
Font getFont();
const Font& getFont();
void setFont (const Font& newFont);
void drawGlyph (int glyphNumber, const AffineTransform& transform);


+ 2
- 42
modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp View File

@@ -2207,53 +2207,13 @@ void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, float le
savedState->fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f));
}
//==============================================================================
class CachedGlyphEdgeTable
{
public:
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
void draw (LowLevelGraphicsSoftwareRenderer::SavedState& state, float x, const float y) const
{
if (snapToIntegerCoordinate)
x = std::floor (x + 0.5f);
if (edgeTable != nullptr)
state.fillEdgeTable (*edgeTable, x, roundToInt (y));
}
void generate (const Font& newFont, const int glyphNumber)
{
font = newFont;
snapToIntegerCoordinate = newFont.getTypeface()->isHinted();
glyph = glyphNumber;
const float fontHeight = font.getHeight();
edgeTable = font.getTypeface()->getEdgeTableForGlyph (glyphNumber,
AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
#if JUCE_MAC || JUCE_IOS
.translated (0.0f, -0.5f)
#endif
);
}
Font font;
int glyph, lastAccessCount;
bool snapToIntegerCoordinate;
private:
ScopedPointer <EdgeTable> edgeTable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable);
};
void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform)
{
Font& f = savedState->font;
if (transform.isOnlyTranslation() && savedState->transform.isOnlyTranslated)
{
RenderingHelpers::GlyphCache <CachedGlyphEdgeTable, SavedState>::getInstance()
RenderingHelpers::GlyphCache <RenderingHelpers::CachedGlyphEdgeTable <LowLevelGraphicsSoftwareRenderer::SavedState>, SavedState>::getInstance()
.drawGlyph (*savedState, f, glyphNumber,
transform.getTranslationX(),
transform.getTranslationY());
@@ -2268,7 +2228,7 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT
}
void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) { savedState->font = newFont; }
Font LowLevelGraphicsSoftwareRenderer::getFont() { return savedState->font; }
const Font& LowLevelGraphicsSoftwareRenderer::getFont() { return savedState->font; }
#if JUCE_MSVC
#pragma warning (pop)


+ 1
- 1
modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h View File

@@ -82,7 +82,7 @@ public:
void drawHorizontalLine (int x, float top, float bottom);
void setFont (const Font&);
Font getFont();
const Font& getFont();
void drawGlyph (int glyphNumber, float x, float y);
void drawGlyph (int glyphNumber, const AffineTransform&);


+ 42
- 0
modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -246,6 +246,48 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache);
};
//==============================================================================
template <class RendererType>
class CachedGlyphEdgeTable
{
public:
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
void draw (RendererType& state, float x, const float y) const
{
if (snapToIntegerCoordinate)
x = std::floor (x + 0.5f);
if (edgeTable != nullptr)
state.fillEdgeTable (*edgeTable, x, roundToInt (y));
}
void generate (const Font& newFont, const int glyphNumber)
{
font = newFont;
Typeface* const typeface = newFont.getTypeface();
snapToIntegerCoordinate = typeface->isHinted();
glyph = glyphNumber;
const float fontHeight = font.getHeight();
edgeTable = typeface->getEdgeTableForGlyph (glyphNumber,
AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
#if JUCE_MAC || JUCE_IOS
.translated (0.0f, -0.5f)
#endif
);
}
Font font;
int glyph, lastAccessCount;
bool snapToIntegerCoordinate;
private:
ScopedPointer <EdgeTable> edgeTable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable);
};
//==============================================================================
template <class StateObjectType>
class SavedStateStack


+ 1
- 1
modules/juce_graphics/native/juce_android_GraphicsContext.cpp View File

@@ -533,7 +533,7 @@ public:
}
}
Font getFont()
const Font& getFont()
{
return currentState->font;
}


+ 1
- 1
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h View File

@@ -70,7 +70,7 @@ public:
void drawVerticalLine (const int x, float top, float bottom);
void drawHorizontalLine (const int y, float left, float right);
void setFont (const Font& newFont);
Font getFont();
const Font& getFont();
void drawGlyph (int glyphNumber, const AffineTransform& transform);
bool drawTextLayout (const AttributedString& text, const Rectangle<float>&);


+ 1
- 1
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -571,7 +571,7 @@ void CoreGraphicsContext::setFont (const Font& newFont)
}
}
Font CoreGraphicsContext::getFont()
const Font& CoreGraphicsContext::getFont()
{
return state->font;
}


+ 1
- 1
modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp View File

@@ -295,7 +295,7 @@ public:
currentState->setFont (newFont);
}
Font getFont()
const Font& getFont()
{
return currentState->font;
}


+ 72
- 113
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -26,19 +26,18 @@
//==============================================================================
struct OpenGLTarget
{
OpenGLTarget (GLuint frameBufferID_, int width_, int height_) noexcept
: frameBuffer (nullptr), frameBufferID (frameBufferID_),
x (0), y (0), width (width_), height (height_)
OpenGLTarget (GLuint frameBufferID_, int width, int height) noexcept
: frameBuffer (nullptr), frameBufferID (frameBufferID_), bounds (width, height)
{}
OpenGLTarget (OpenGLFrameBuffer& frameBuffer_, const Point<int>& origin) noexcept
: frameBuffer (&frameBuffer_), frameBufferID (0), x (origin.x), y (origin.y),
width (frameBuffer_.getWidth()), height (frameBuffer_.getHeight())
: frameBuffer (&frameBuffer_), frameBufferID (0),
bounds (origin.x, origin.y, frameBuffer_.getWidth(), frameBuffer_.getHeight())
{}
OpenGLTarget (const OpenGLTarget& other) noexcept
: frameBuffer (other.frameBuffer), frameBufferID (other.frameBufferID),
x (other.x), y (other.y), width (other.width), height (other.height)
bounds (other.bounds)
{}
void makeActiveFor2D() const
@@ -49,9 +48,9 @@ struct OpenGLTarget
OpenGLFrameBuffer::setCurrentFrameBufferTarget (frameBufferID);
#if JUCE_USE_OPENGL_FIXED_FUNCTION
applyFlippedMatrix (x, y, width, height);
applyFlippedMatrix (bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
#else
glViewport (0, 0, width, height);
glViewport (0, 0, bounds.getWidth(), bounds.getHeight());
#endif
glDisable (GL_DEPTH_TEST);
}
@@ -59,8 +58,8 @@ struct OpenGLTarget
#if JUCE_USE_OPENGL_FIXED_FUNCTION
void scissor (Rectangle<int> r) const
{
r = r.translated (-x, -y);
OpenGLHelpers::enableScissorTest (r.withY (height - r.getBottom()));
r -= bounds.getPosition();
OpenGLHelpers::enableScissorTest (r.withY (bounds.getHeight() - r.getBottom()));
}
static void applyFlippedMatrix (const int x, const int y, const int width, const int height)
@@ -80,35 +79,8 @@ struct OpenGLTarget
OpenGLFrameBuffer* frameBuffer;
GLuint frameBufferID;
int x, y, width, height;
};
struct ClippedEdgeTable
{
ClippedEdgeTable (const EdgeTable& et, const Rectangle<int>& clip)
: table (&et)
{
if (! clip.contains (et.getMaximumBounds()))
{
clipped = new EdgeTable (clip);
clipped->clipToEdgeTable (et);
table = clipped;
}
}
ClippedEdgeTable (const EdgeTable& et, const RectangleList& clip)
: table (&et)
{
if (! clip.containsRectangle (et.getMaximumBounds()))
{
clipped = new EdgeTable (clip);
clipped->clipToEdgeTable (et);
table = clipped;
}
}
const EdgeTable* table;
ScopedPointer<EdgeTable> clipped;
Rectangle<int> bounds;
};
//==============================================================================
@@ -118,12 +90,16 @@ public:
PositionedTexture (OpenGLTexture& texture, const EdgeTable& et, const Rectangle<int>& clip_)
: clip (clip_.getIntersection (et.getMaximumBounds()))
{
const ClippedEdgeTable clippedTable (et, clip);
EdgeTableAlphaMap alphaMap (*(clippedTable.table));
texture.loadAlpha (alphaMap.data, alphaMap.area.getWidth(), alphaMap.area.getHeight());
textureID = texture.getTextureID();
area = alphaMap.area;
if (clip.contains (et.getMaximumBounds()))
{
createMap (texture, et);
}
else
{
EdgeTable et2 (clip);
et2.clipToEdgeTable (et);
createMap (texture, et2);
}
}
PositionedTexture (GLuint textureID_, const Rectangle<int> area_, const Rectangle<int> clip_) noexcept
@@ -156,6 +132,14 @@ public:
Rectangle<int> area, clip;
private:
void createMap (OpenGLTexture& texture, const EdgeTable& et)
{
EdgeTableAlphaMap alphaMap (et);
texture.loadAlpha (alphaMap.data, alphaMap.area.getWidth(), alphaMap.area.getHeight());
textureID = texture.getTextureID();
area = alphaMap.area;
}
struct EdgeTableAlphaMap
{
EdgeTableAlphaMap (const EdgeTable& et)
@@ -267,9 +251,11 @@ public:
maskBounds (program, "maskBounds")
{}
void setBounds (const Rectangle<int>& area, const OpenGLTarget& target) const
void setBounds (const Rectangle<int>& area, const OpenGLTarget& target, const GLint textureIndex) const
{
maskBounds.set (area.getX() - target.x, target.height - (area.getBottom() - target.y),
maskTexture.set (textureIndex);
maskBounds.set (area.getX() - target.bounds.getX(),
target.bounds.getHeight() - (area.getBottom() - target.bounds.getY()),
area.getWidth(), area.getHeight());
}
@@ -284,8 +270,7 @@ public:
"{"
" gl_FragColor = gl_Color;"
"}")
{
}
{}
};
#define JUCE_DECLARE_SHADER_VERSION "#version 120\n"
@@ -305,8 +290,7 @@ public:
"gl_FragColor = gl_Color * " JUCE_GET_MASK_ALPHA ";"
"}"),
maskParams (program)
{
}
{}
MaskedShaderParams maskParams;
};
@@ -1090,6 +1074,7 @@ struct StateHelpers
~ShaderQuadQueue() noexcept
{
static_jassert (sizeof (VertexInfo) == 8);
glDeleteBuffers (2, buffers);
}
@@ -1237,7 +1222,7 @@ struct StateHelpers
void setShader (OpenGLTarget& target, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader)
{
setShader (Rectangle<int> (target.x, target.y, target.width, target.height), quadQueue, shader);
setShader (target.bounds, quadQueue, shader);
}
void clearShader (ShaderQuadQueue& quadQueue)
@@ -1278,15 +1263,34 @@ public:
#if JUCE_USE_OPENGL_FIXED_FUNCTION
currentColour.resync();
#endif
#ifdef GL_COLOR_ARRAY
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
#if JUCE_USE_OPENGL_SHADERS
if (currentShader.canUseShaders)
{
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_INDEX_ARRAY);
for (int i = 3; --i >= 0;)
for (int i = 3; --i >= 0;)
{
activeTextures.setActiveTexture (i);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
}
}
else
#endif
{
activeTextures.setActiveTexture (i);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
for (int i = 3; --i >= 0;)
{
activeTextures.setActiveTexture (i);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
}
#endif
@@ -1620,8 +1624,8 @@ public:
textureCache.bindTextureForGradient (activeTextures, g);
}
const AffineTransform t (transform.translated ((float) -target.x, (float) -target.y)
.followedBy (AffineTransform::verticalFlip ((float) target.height)));
const AffineTransform t (transform.translated ((float) -target.bounds.getX(), (float) -target.bounds.getY())
.followedBy (AffineTransform::verticalFlip ((float) target.bounds.getHeight())));
Point<float> p1 (g.point1.transformedBy (t));
const Point<float> p2 (g.point2.transformedBy (t));
const Point<float> p3 (Point<float> (g.point1.x + (g.point2.y - g.point1.y),
@@ -1694,10 +1698,7 @@ public:
}
if (maskParams != nullptr)
{
maskParams->maskTexture.set ((GLint) 1);
maskParams->setBounds (*maskArea, target);
}
maskParams->setBounds (*maskArea, target, 1);
}
void setShaderForTiledImageFill (const OpenGLTextureFromImage& image, const AffineTransform& transform,
@@ -1744,13 +1745,11 @@ public:
}
}
imageParams->setMatrix (transform, image, (float) target.x, (float) target.y, (float) target.height);
imageParams->setMatrix (transform, image, (float) target.bounds.getX(),
(float) target.bounds.getY(), (float) target.bounds.getHeight());
if (maskParams != nullptr)
{
maskParams->maskTexture.set ((GLint) 1);
maskParams->setBounds (*maskArea, target);
}
maskParams->setBounds (*maskArea, target, 1);
}
#endif
@@ -2625,7 +2624,7 @@ private:
state.activeTextures.bindTexture (maskTextureID);
state.setShader (state.currentShader.programs->solidColourMasked);
state.currentShader.programs->solidColourMasked.maskParams.setBounds (clip.maskArea, state.target);
state.currentShader.programs->solidColourMasked.maskParams.setBounds (clip.maskArea, state.target, 0);
}
else if (fill.isGradient())
{
@@ -2729,13 +2728,14 @@ public:
void fillRect (const Rectangle<float>& area, const FillType& fill)
{
const PixelARGB colour (fill.colour.getPixelARGB());
ShaderFillOperation fillOp (*this, fill, false, false);
for (RectangleList::Iterator i (clip); i.next();)
{
const Rectangle<float> r (i.getRectangle()->toFloat().getIntersection (area));
if (! r.isEmpty())
state.shaderQuadQueue.add (r, fill.colour.getPixelARGB());
state.shaderQuadQueue.add (r, colour);
}
}
@@ -2822,7 +2822,7 @@ class OpenGLGraphicsContext::SavedState
{
public:
SavedState (OpenGLGraphicsContext::GLState* const state_)
: clip (createRectangleClip (*state_, Rectangle<int> (state_->target.width, state_->target.height))),
: clip (createRectangleClip (*state_, state_->target.bounds)),
transform (0, 0), interpolationQuality (Graphics::mediumResamplingQuality),
state (state_), transparencyLayerAlpha (1.0f)
{
@@ -3049,7 +3049,7 @@ public:
{
if (transform.isOnlyTranslated && t.isOnlyTranslation())
{
RenderingHelpers::GlyphCache <CachedGlyphEdgeTable, SavedState>::getInstance()
RenderingHelpers::GlyphCache <RenderingHelpers::CachedGlyphEdgeTable <OpenGLGraphicsContext::SavedState>, SavedState>::getInstance()
.drawGlyph (*this, font, glyphNumber,
transform.xOffset + t.getTranslationX(),
transform.yOffset + t.getTranslationY());
@@ -3156,45 +3156,6 @@ private:
clip->fillEdgeTable (et, getFillType());
}
class CachedGlyphEdgeTable
{
public:
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
void draw (OpenGLGraphicsContext::SavedState& state, float x, const float y) const
{
if (snapToIntegerCoordinate)
x = std::floor (x + 0.5f);
if (edgeTable != nullptr)
state.fillEdgeTable (*edgeTable, x, roundToInt (y));
}
void generate (const Font& newFont, const int glyphNumber)
{
font = newFont;
snapToIntegerCoordinate = newFont.getTypeface()->isHinted();
glyph = glyphNumber;
const float fontHeight = font.getHeight();
edgeTable = font.getTypeface()->getEdgeTableForGlyph (glyphNumber,
AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
#if JUCE_MAC || JUCE_IOS
.translated (0.0f, -0.5f)
#endif
);
}
Font font;
int glyph, lastAccessCount;
bool snapToIntegerCoordinate;
private:
ScopedPointer <EdgeTable> edgeTable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable);
};
SavedState& operator= (const SavedState&);
};
@@ -3217,9 +3178,7 @@ OpenGLGraphicsContext::OpenGLGraphicsContext (unsigned int frameBufferID, int wi
{
}
OpenGLGraphicsContext::~OpenGLGraphicsContext()
{
}
OpenGLGraphicsContext::~OpenGLGraphicsContext() {}
bool OpenGLGraphicsContext::isVectorDevice() const { return false; }
void OpenGLGraphicsContext::setOrigin (int x, int y) { stack->transform.setOrigin (x, y); }
@@ -3248,4 +3207,4 @@ void OpenGLGraphicsContext::drawHorizontalLine (int y, float left, float right)
void OpenGLGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& t) { stack->drawGlyph (glyphNumber, t); }
void OpenGLGraphicsContext::drawLine (const Line <float>& line) { stack->drawLine (line); }
void OpenGLGraphicsContext::setFont (const Font& newFont) { stack->font = newFont; }
Font OpenGLGraphicsContext::getFont() { return stack->font; }
const Font& OpenGLGraphicsContext::getFont() { return stack->font; }

+ 1
- 1
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h View File

@@ -69,7 +69,7 @@ public:
void drawHorizontalLine (int y, float left, float right);
void setFont (const Font&);
Font getFont();
const Font& getFont();
void drawGlyph (int glyphNumber, const AffineTransform&);


Loading…
Cancel
Save