blob: b061e45ebdedef288a8e18748c092ac59106906b [file] [log] [blame]
Markus Tavenrathcb9609f2018-12-26 00:52:44 +09001//
Jamie Madill60a50cf2018-12-29 16:04:05 -05002// Copyright 2018 The ANGLE Project Authors. All rights reserved.
Markus Tavenrathcb9609f2018-12-26 00:52:44 +09003// 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;
Jamie Madillc09ae152019-02-01 14:16:32 -050020#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR)
Markus Tavenrathcb9609f2018-12-26 00:52:44 +090021
22namespace gl
23{
Jamie Madill60a50cf2018-12-29 16:04:05 -050024constexpr 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
38ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
39 GLsizei count,
40 GLsizei instanceCount)
41{
42 if (context->getStateCache().isTransformFeedbackActiveUnpaused())
43 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -050044 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Jamie Madill60a50cf2018-12-29 16:04:05 -050045 transformFeedback->onVerticesDrawn(context, count, instanceCount);
46 }
47}
48
Shahbaz Youssefi248119b2020-07-20 16:05:45 -040049ANGLE_INLINE void MarkShaderStorageUsage(const Context *context)
James Dong020abb82019-07-24 11:33:49 -060050{
51 for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
52 {
Shahbaz Youssefi248119b2020-07-20 16:05:45 -040053 Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
James Dong020abb82019-07-24 11:33:49 -060054 if (buffer)
55 {
56 buffer->onDataChanged();
57 }
58 }
Shahbaz Youssefi248119b2020-07-20 16:05:45 -040059
60 for (size_t index : context->getStateCache().getActiveImageUnitIndices())
61 {
62 const ImageUnit &imageUnit = context->getState().getImageUnit(index);
63 const Texture *texture = imageUnit.texture.get();
64 if (texture)
65 {
66 texture->onStateChange(angle::SubjectMessage::ContentsChanged);
67 }
68 }
James Dong020abb82019-07-24 11:33:49 -060069}
70
Jamie Madill60a50cf2018-12-29 16:04:05 -050071// Return true if the draw is a no-op, else return false.
Tim Van Patten405f8e72020-02-24 17:38:10 -070072// If there is no active program for the vertex or fragment shader stages, the results of vertex
73// and fragment shader execution will respectively be undefined. However, this is not
74// an error. ANGLE will treat this as a no-op.
Jamie Madill60a50cf2018-12-29 16:04:05 -050075// A no-op draw occurs if the count of vertices is less than the minimum required to
76// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
shrekshao796df762020-06-25 11:49:12 -070077ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const
Jamie Madill60a50cf2018-12-29 16:04:05 -050078{
Tim Van Patten12b6a822020-04-03 18:31:22 -060079 if (!mStateCache.getCanDraw())
80 {
81 return true;
82 }
83
Jamie Madilld03b15b2020-03-26 17:22:18 -040084 return count < kMinimumPrimitiveCounts[mode];
Jamie Madill60a50cf2018-12-29 16:04:05 -050085}
Markus Tavenrathcb9609f2018-12-26 00:52:44 +090086
87ANGLE_INLINE angle::Result Context::syncDirtyBits()
88{
Jamie Madillc3dc5d42018-12-30 12:12:04 -050089 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Markus Tavenrathcb9609f2018-12-26 00:52:44 +090090 ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits));
Jamie Madillc3dc5d42018-12-30 12:12:04 -050091 mState.clearDirtyBits();
Markus Tavenrathcb9609f2018-12-26 00:52:44 +090092 return angle::Result::Continue;
93}
94
95ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask)
96{
Jamie Madillc3dc5d42018-12-30 12:12:04 -050097 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Markus Tavenrathcb9609f2018-12-26 00:52:44 +090098 ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask));
Jamie Madillc3dc5d42018-12-30 12:12:04 -050099 mState.clearDirtyBits(dirtyBits);
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900100 return angle::Result::Continue;
101}
102
Tim Van Patten81370212020-07-29 12:54:02 -0600103ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask,
104 Command command)
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900105{
Tim Van Patten81370212020-07-29 12:54:02 -0600106 return mState.syncDirtyObjects(this, objectMask, command);
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900107}
108
109ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
110{
111 if (mGLES1Renderer)
112 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500113 ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState));
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900114 }
115
Tim Van Patten81370212020-07-29 12:54:02 -0600116 ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw));
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900117 ASSERT(!isRobustResourceInitEnabled() ||
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500118 !mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900119 return syncDirtyBits();
120}
121
Jamie Madill60a50cf2018-12-29 16:04:05 -0500122ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
123{
124 // No-op if count draws no primitives for given mode
125 if (noopDraw(mode, count))
126 {
127 return;
128 }
129
130 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
131 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
132 MarkTransformFeedbackBufferUsage(this, count, 1);
133}
134
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900135ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
136 GLsizei count,
137 DrawElementsType type,
138 const void *indices)
139{
140 // No-op if count draws no primitives for given mode
141 if (noopDraw(mode, count))
142 {
143 return;
144 }
145
146 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
147 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
148}
149
Jamie Madill60a50cf2018-12-29 16:04:05 -0500150ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
151{
152 updateBasicDrawStatesError();
153 updateBasicDrawElementsError();
154}
155
Jamie Madill3b3fe832019-08-06 17:44:12 -0400156ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer)
Jamie Madill60a50cf2018-12-29 16:04:05 -0500157{
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500158 Buffer *bufferObject =
159 mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
160 mState.setBufferBinding(this, target, bufferObject);
Jamie Madill60a50cf2018-12-29 16:04:05 -0500161 mStateCache.onBufferBindingChange(this);
162}
163
Markus Tavenrathcb9609f2018-12-26 00:52:44 +0900164} // namespace gl
165
166#endif // LIBANGLE_CONTEXT_INL_H_