diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/canvas/WebGLTransformFeedback.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/canvas/WebGLTransformFeedback.cpp')
-rw-r--r-- | dom/canvas/WebGLTransformFeedback.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/dom/canvas/WebGLTransformFeedback.cpp b/dom/canvas/WebGLTransformFeedback.cpp new file mode 100644 index 000000000..feec581ea --- /dev/null +++ b/dom/canvas/WebGLTransformFeedback.cpp @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLTransformFeedback.h" + +#include "GLContext.h" +#include "mozilla/dom/WebGL2RenderingContextBinding.h" +#include "WebGL2Context.h" + +namespace mozilla { + +WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl, GLuint tf) + : WebGLRefCountedObject(webgl) + , mGLName(tf) + , mIndexedBindings(webgl->mGLMaxTransformFeedbackSeparateAttribs) + , mIsPaused(false) + , mIsActive(false) +{ + mContext->mTransformFeedbacks.insertBack(this); +} + +WebGLTransformFeedback::~WebGLTransformFeedback() +{ + DeleteOnce(); +} + +void +WebGLTransformFeedback::Delete() +{ + if (mGLName) { + mContext->MakeContextCurrent(); + mContext->gl->fDeleteTransformFeedbacks(1, &mGLName); + } + removeFrom(mContext->mTransformFeedbacks); +} + +//////////////////////////////////////// + +void +WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) +{ + const char funcName[] = "beginTransformFeedback"; + + if (mIsActive) + return mContext->ErrorInvalidOperation("%s: Already active.", funcName); + + switch (primMode) { + case LOCAL_GL_POINTS: + case LOCAL_GL_LINES: + case LOCAL_GL_TRIANGLES: + break; + default: + mContext->ErrorInvalidEnum("%s: `primitiveMode` must be one of POINTS, LINES, or" + " TRIANGLES.", + funcName); + return; + } + + const auto& prog = mContext->mCurrentProgram; + if (!prog || + !prog->IsLinked() || + !prog->LinkInfo()->componentsPerTFVert.size()) + { + mContext->ErrorInvalidOperation("%s: Current program not valid for transform" + " feedback.", + funcName); + return; + } + + const auto& linkInfo = prog->LinkInfo(); + const auto& componentsPerTFVert = linkInfo->componentsPerTFVert; + + size_t minVertCapacity = SIZE_MAX; + for (size_t i = 0; i < componentsPerTFVert.size(); i++) { + const auto& indexedBinding = mIndexedBindings[i]; + const auto& componentsPerVert = componentsPerTFVert[i]; + + const auto& buffer = indexedBinding.mBufferBinding; + if (!buffer) { + mContext->ErrorInvalidOperation("%s: No buffer attached to required transform" + " feedback index %u.", + funcName, (uint32_t)i); + return; + } + + const size_t vertCapacity = buffer->ByteLength() / 4 / componentsPerVert; + minVertCapacity = std::min(minVertCapacity, vertCapacity); + } + + //// + + const auto& gl = mContext->gl; + gl->MakeCurrent(); + gl->fBeginTransformFeedback(primMode); + + //// + + mIsActive = true; + MOZ_ASSERT(!mIsPaused); + + mActive_Program = prog; + mActive_PrimMode = primMode; + mActive_VertPosition = 0; + mActive_VertCapacity = minVertCapacity; + + //// + + mActive_Program->mNumActiveTFOs++; +} + + +void +WebGLTransformFeedback::EndTransformFeedback() +{ + const char funcName[] = "endTransformFeedback"; + + if (!mIsActive) + return mContext->ErrorInvalidOperation("%s: Not active.", funcName); + + //// + + const auto& gl = mContext->gl; + gl->MakeCurrent(); + gl->fEndTransformFeedback(); + + //// + + mIsActive = false; + mIsPaused = false; + + //// + + mActive_Program->mNumActiveTFOs--; +} + +void +WebGLTransformFeedback::PauseTransformFeedback() +{ + const char funcName[] = "pauseTransformFeedback"; + + if (!mIsActive || + mIsPaused) + { + mContext->ErrorInvalidOperation("%s: Not active or is paused.", funcName); + return; + } + + //// + + const auto& gl = mContext->gl; + gl->MakeCurrent(); + gl->fPauseTransformFeedback(); + + //// + + mIsPaused = true; +} + +void +WebGLTransformFeedback::ResumeTransformFeedback() +{ + const char funcName[] = "resumeTransformFeedback"; + + if (!mIsPaused) + return mContext->ErrorInvalidOperation("%s: Not paused.", funcName); + + if (mContext->mCurrentProgram != mActive_Program) { + mContext->ErrorInvalidOperation("%s: Active program differs from original.", + funcName); + return; + } + + //// + + const auto& gl = mContext->gl; + gl->MakeCurrent(); + gl->fResumeTransformFeedback(); + + //// + + MOZ_ASSERT(mIsActive); + mIsPaused = false; +} + +//////////////////////////////////////// + +void +WebGLTransformFeedback::AddBufferBindCounts(int8_t addVal) const +{ + const GLenum target = LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER; + WebGLBuffer::AddBindCount(target, mGenericBufferBinding.get(), addVal); + for (const auto& binding : mIndexedBindings) { + WebGLBuffer::AddBindCount(target, binding.mBufferBinding.get(), addVal); + } +} + +//////////////////////////////////////// + +JSObject* +WebGLTransformFeedback::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) +{ + return dom::WebGLTransformFeedbackBinding::Wrap(cx, this, givenProto); +} + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTransformFeedback, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTransformFeedback, Release) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLTransformFeedback, + mGenericBufferBinding, + mIndexedBindings, + mActive_Program) + +} // namespace mozilla |