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