diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Context.inl.h')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/Context.inl.h | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Context.inl.h b/gfx/angle/checkout/src/libANGLE/Context.inl.h new file mode 100644 index 0000000000..3a0573d307 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Context.inl.h @@ -0,0 +1,176 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Context.inl.h: Defines inline functions of gl::Context class +// Has to be included after libANGLE/Context.h when using one +// of the defined functions + +#ifndef LIBANGLE_CONTEXT_INL_H_ +#define LIBANGLE_CONTEXT_INL_H_ + +#include "libANGLE/Context.h" +#include "libANGLE/GLES1Renderer.h" +#include "libANGLE/renderer/ContextImpl.h" + +#define ANGLE_HANDLE_ERR(X) \ + (void)(X); \ + return; +#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR) + +namespace gl +{ +constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{ + {PrimitiveMode::Points, 1}, + {PrimitiveMode::Lines, 2}, + {PrimitiveMode::LineLoop, 2}, + {PrimitiveMode::LineStrip, 2}, + {PrimitiveMode::Triangles, 3}, + {PrimitiveMode::TriangleStrip, 3}, + {PrimitiveMode::TriangleFan, 3}, + {PrimitiveMode::LinesAdjacency, 2}, + {PrimitiveMode::LineStripAdjacency, 2}, + {PrimitiveMode::TrianglesAdjacency, 3}, + {PrimitiveMode::TriangleStripAdjacency, 3}, +}}; + +ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context, + GLsizei count, + GLsizei instanceCount) +{ + if (context->getStateCache().isTransformFeedbackActiveUnpaused()) + { + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + transformFeedback->onVerticesDrawn(context, count, instanceCount); + } +} + +ANGLE_INLINE void MarkShaderStorageUsage(const Context *context) +{ + for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices()) + { + Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get(); + if (buffer) + { + buffer->onDataChanged(); + } + } + + for (size_t index : context->getStateCache().getActiveImageUnitIndices()) + { + const ImageUnit &imageUnit = context->getState().getImageUnit(index); + const Texture *texture = imageUnit.texture.get(); + if (texture) + { + texture->onStateChange(angle::SubjectMessage::ContentsChanged); + } + } +} + +// Return true if the draw is a no-op, else return false. +// If there is no active program for the vertex or fragment shader stages, the results of vertex +// and fragment shader execution will respectively be undefined. However, this is not +// an error. ANGLE will treat this as a no-op. +// A no-op draw occurs if the count of vertices is less than the minimum required to +// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris). +ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const +{ + if (!mStateCache.getCanDraw()) + { + return true; + } + + return count < kMinimumPrimitiveCounts[mode]; +} + +ANGLE_INLINE angle::Result Context::syncDirtyBits(Command command) +{ + const State::DirtyBits &dirtyBits = mState.getDirtyBits(); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, command)); + mState.clearDirtyBits(); + return angle::Result::Continue; +} + +ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, Command command) +{ + const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, command)); + mState.clearDirtyBits(dirtyBits); + return angle::Result::Continue; +} + +ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask, + Command command) +{ + return mState.syncDirtyObjects(this, objectMask, command); +} + +ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode) +{ + if (mGLES1Renderer) + { + ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState)); + } + + ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw)); + ASSERT(!isRobustResourceInitEnabled() || + !mState.getDrawFramebuffer()->hasResourceThatNeedsInit()); + return syncDirtyBits(Command::Draw); +} + +ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count)); + MarkTransformFeedbackBufferUsage(this, count, 1); +} + +ANGLE_INLINE void Context::drawElements(PrimitiveMode mode, + GLsizei count, + DrawElementsType type, + const void *indices) +{ + // No-op if count draws no primitives for given mode + if (noopDraw(mode, count)) + { + ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent()); + return; + } + + ANGLE_CONTEXT_TRY(prepareForDraw(mode)); + ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices)); +} + +ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context) +{ + updateBasicDrawStatesError(); + updateBasicDrawElementsError(); +} + +ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer) +{ + Buffer *bufferObject = + mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer); + + // Early return if rebinding the same buffer + if (bufferObject == mState.getTargetBuffer(target)) + { + return; + } + + mState.setBufferBinding(this, target, bufferObject); + mStateCache.onBufferBindingChange(this); +} + +} // namespace gl + +#endif // LIBANGLE_CONTEXT_INL_H_ |