tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Context.inl.h (5899B)


      1 //
      2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Context.inl.h: Defines inline functions of gl::Context class
      8 // Has to be included after libANGLE/Context.h when using one
      9 // of the defined functions
     10 
     11 #ifndef LIBANGLE_CONTEXT_INL_H_
     12 #define LIBANGLE_CONTEXT_INL_H_
     13 
     14 #include "libANGLE/Context.h"
     15 #include "libANGLE/GLES1Renderer.h"
     16 #include "libANGLE/renderer/ContextImpl.h"
     17 
     18 #define ANGLE_HANDLE_ERR(X) \
     19    (void)(X);              \
     20    return;
     21 #define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR)
     22 
     23 namespace gl
     24 {
     25 constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
     26    {PrimitiveMode::Points, 1},
     27    {PrimitiveMode::Lines, 2},
     28    {PrimitiveMode::LineLoop, 2},
     29    {PrimitiveMode::LineStrip, 2},
     30    {PrimitiveMode::Triangles, 3},
     31    {PrimitiveMode::TriangleStrip, 3},
     32    {PrimitiveMode::TriangleFan, 3},
     33    {PrimitiveMode::LinesAdjacency, 2},
     34    {PrimitiveMode::LineStripAdjacency, 2},
     35    {PrimitiveMode::TrianglesAdjacency, 3},
     36    {PrimitiveMode::TriangleStripAdjacency, 3},
     37 }};
     38 
     39 ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
     40                                                   GLsizei count,
     41                                                   GLsizei instanceCount)
     42 {
     43    if (context->getStateCache().isTransformFeedbackActiveUnpaused())
     44    {
     45        TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
     46        transformFeedback->onVerticesDrawn(context, count, instanceCount);
     47    }
     48 }
     49 
     50 ANGLE_INLINE void MarkShaderStorageUsage(const Context *context)
     51 {
     52    for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
     53    {
     54        Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
     55        if (buffer)
     56        {
     57            buffer->onDataChanged();
     58        }
     59    }
     60 
     61    for (size_t index : context->getStateCache().getActiveImageUnitIndices())
     62    {
     63        const ImageUnit &imageUnit = context->getState().getImageUnit(index);
     64        const Texture *texture     = imageUnit.texture.get();
     65        if (texture)
     66        {
     67            texture->onStateChange(angle::SubjectMessage::ContentsChanged);
     68        }
     69    }
     70 }
     71 
     72 // Return true if the draw is a no-op, else return false.
     73 //  If there is no active program for the vertex or fragment shader stages, the results of vertex
     74 //  and fragment shader execution will respectively be undefined. However, this is not
     75 //  an error. ANGLE will treat this as a no-op.
     76 //  A no-op draw occurs if the count of vertices is less than the minimum required to
     77 //  have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
     78 ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const
     79 {
     80    if (!mStateCache.getCanDraw())
     81    {
     82        return true;
     83    }
     84 
     85    return count < kMinimumPrimitiveCounts[mode];
     86 }
     87 
     88 ANGLE_INLINE angle::Result Context::syncDirtyBits(Command command)
     89 {
     90    const State::DirtyBits &dirtyBits = mState.getDirtyBits();
     91    ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, command));
     92    mState.clearDirtyBits();
     93    return angle::Result::Continue;
     94 }
     95 
     96 ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, Command command)
     97 {
     98    const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
     99    ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, command));
    100    mState.clearDirtyBits(dirtyBits);
    101    return angle::Result::Continue;
    102 }
    103 
    104 ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask,
    105                                                     Command command)
    106 {
    107    return mState.syncDirtyObjects(this, objectMask, command);
    108 }
    109 
    110 ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
    111 {
    112    if (mGLES1Renderer)
    113    {
    114        ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState));
    115    }
    116 
    117    ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw));
    118    ASSERT(!isRobustResourceInitEnabled() ||
    119           !mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
    120    return syncDirtyBits(Command::Draw);
    121 }
    122 
    123 ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
    124 {
    125    // No-op if count draws no primitives for given mode
    126    if (noopDraw(mode, count))
    127    {
    128        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
    129        return;
    130    }
    131 
    132    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
    133    ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
    134    MarkTransformFeedbackBufferUsage(this, count, 1);
    135 }
    136 
    137 ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
    138                                        GLsizei count,
    139                                        DrawElementsType type,
    140                                        const void *indices)
    141 {
    142    // No-op if count draws no primitives for given mode
    143    if (noopDraw(mode, count))
    144    {
    145        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
    146        return;
    147    }
    148 
    149    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
    150    ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
    151 }
    152 
    153 ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
    154 {
    155    updateBasicDrawStatesError();
    156    updateBasicDrawElementsError();
    157 }
    158 
    159 ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer)
    160 {
    161    Buffer *bufferObject =
    162        mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
    163 
    164    // Early return if rebinding the same buffer
    165    if (bufferObject == mState.getTargetBuffer(target))
    166    {
    167        return;
    168    }
    169 
    170    mState.setBufferBinding(this, target, bufferObject);
    171    mStateCache.onBufferBindingChange(this);
    172 }
    173 
    174 }  // namespace gl
    175 
    176 #endif  // LIBANGLE_CONTEXT_INL_H_