• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GLES1Renderer.h"
15 #include "libANGLE/renderer/ContextImpl.h"
16 
17 #define ANGLE_HANDLE_ERR(X) \
18     (void)(X);              \
19     return;
20 #define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR)
21 
22 namespace gl
23 {
24 constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
25     {PrimitiveMode::Points, 1},
26     {PrimitiveMode::Lines, 2},
27     {PrimitiveMode::LineLoop, 2},
28     {PrimitiveMode::LineStrip, 2},
29     {PrimitiveMode::Triangles, 3},
30     {PrimitiveMode::TriangleStrip, 3},
31     {PrimitiveMode::TriangleFan, 3},
32     {PrimitiveMode::LinesAdjacency, 2},
33     {PrimitiveMode::LineStripAdjacency, 2},
34     {PrimitiveMode::TrianglesAdjacency, 3},
35     {PrimitiveMode::TriangleStripAdjacency, 3},
36 }};
37 
MarkTransformFeedbackBufferUsage(const Context * context,GLsizei count,GLsizei instanceCount)38 ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
39                                                    GLsizei count,
40                                                    GLsizei instanceCount)
41 {
42     if (context->getStateCache().isTransformFeedbackActiveUnpaused())
43     {
44         TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
45         transformFeedback->onVerticesDrawn(context, count, instanceCount);
46     }
47 }
48 
MarkShaderStorageBufferUsage(const Context * context)49 ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context)
50 {
51     for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
52     {
53         gl::Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
54         if (buffer)
55         {
56             buffer->onDataChanged();
57         }
58     }
59 }
60 
61 // Return true if the draw is a no-op, else return false.
62 //  If there is no active program for the vertex or fragment shader stages, the results of vertex
63 //  and fragment shader execution will respectively be undefined. However, this is not
64 //  an error. ANGLE will treat this as a no-op.
65 //  A no-op draw occurs if the count of vertices is less than the minimum required to
66 //  have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
noopDraw(PrimitiveMode mode,GLsizei count)67 ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count)
68 {
69     if (!mStateCache.getCanDraw())
70     {
71         return true;
72     }
73 
74     return count < kMinimumPrimitiveCounts[mode];
75 }
76 
syncDirtyBits()77 ANGLE_INLINE angle::Result Context::syncDirtyBits()
78 {
79     const State::DirtyBits &dirtyBits = mState.getDirtyBits();
80     ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits));
81     mState.clearDirtyBits();
82     return angle::Result::Continue;
83 }
84 
syncDirtyBits(const State::DirtyBits & bitMask)85 ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask)
86 {
87     const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
88     ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask));
89     mState.clearDirtyBits(dirtyBits);
90     return angle::Result::Continue;
91 }
92 
syncDirtyObjects(const State::DirtyObjects & objectMask)93 ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask)
94 {
95     return mState.syncDirtyObjects(this, objectMask);
96 }
97 
prepareForDraw(PrimitiveMode mode)98 ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
99 {
100     if (mGLES1Renderer)
101     {
102         ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState));
103     }
104 
105     ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects));
106     ASSERT(!isRobustResourceInitEnabled() ||
107            !mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
108     return syncDirtyBits();
109 }
110 
drawArrays(PrimitiveMode mode,GLint first,GLsizei count)111 ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
112 {
113     // No-op if count draws no primitives for given mode
114     if (noopDraw(mode, count))
115     {
116         return;
117     }
118 
119     ANGLE_CONTEXT_TRY(prepareForDraw(mode));
120     ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
121     MarkTransformFeedbackBufferUsage(this, count, 1);
122 }
123 
drawElements(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices)124 ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
125                                         GLsizei count,
126                                         DrawElementsType type,
127                                         const void *indices)
128 {
129     // No-op if count draws no primitives for given mode
130     if (noopDraw(mode, count))
131     {
132         return;
133     }
134 
135     ANGLE_CONTEXT_TRY(prepareForDraw(mode));
136     ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
137 }
138 
onBufferBindingChange(Context * context)139 ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
140 {
141     updateBasicDrawStatesError();
142     updateBasicDrawElementsError();
143 }
144 
bindBuffer(BufferBinding target,BufferID buffer)145 ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer)
146 {
147     Buffer *bufferObject =
148         mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
149     mState.setBufferBinding(this, target, bufferObject);
150     mStateCache.onBufferBindingChange(this);
151 }
152 
153 }  // namespace gl
154 
155 #endif  // LIBANGLE_CONTEXT_INL_H_
156