| /* |
| * Copyright 2015, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // Note this file is included in context in gles_spy.h: |
| // |
| // namespace gapii { |
| // |
| // class GlesSpy { |
| // protected: |
| |
| typedef uint32_t GLenum_Error; |
| std::unordered_map<gapii::ContextID, GLenum_Error> mErrors; |
| |
| template<typename T> T inline min(T a, T b) { return (a < b) ? a : b; } |
| template<typename T> T inline max(T a, T b) { return (a > b) ? a : b; } |
| |
| // Externs not implemented in GAPII. |
| template <typename T> inline void mapMemory(const T&) {} |
| template <typename T> inline void unmapMemory(const T&) {} |
| template <typename T> inline void resolveAttributesAndUniforms(const T&, int32_t) {} |
| |
| |
| inline uint32_t minIndex(const uint8_t* indices, uint32_t indices_type, uint32_t offset, uint32_t count) { |
| uint32_t v = ~(uint32_t)0; |
| switch (indices_type) { |
| case gapii::GLenum::GL_UNSIGNED_BYTE: { |
| const uint8_t* p = reinterpret_cast<const uint8_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = min<uint32_t>(v, p[i]); } |
| break; |
| } |
| case gapii::GLenum::GL_UNSIGNED_SHORT: { |
| const uint16_t* p = reinterpret_cast<const uint16_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = min<uint32_t>(v, p[i]); } |
| break; |
| } |
| case gapii::GLenum::GL_UNSIGNED_INT: { |
| const uint32_t* p = reinterpret_cast<const uint32_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = min<uint32_t>(v, p[i]); } |
| break; |
| } |
| } |
| return v; |
| } |
| |
| inline uint32_t maxIndex(const uint8_t* indices, uint32_t indices_type, uint32_t offset, uint32_t count) { |
| uint32_t v = 0; |
| switch (indices_type) { |
| case gapii::GLenum::GL_UNSIGNED_BYTE: { |
| const uint8_t* p = reinterpret_cast<const uint8_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = max<uint32_t>(v, p[i]); } |
| break; |
| } |
| case gapii::GLenum::GL_UNSIGNED_SHORT: { |
| const uint16_t* p = reinterpret_cast<const uint16_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = max<uint32_t>(v, p[i]); } |
| break; |
| } |
| case gapii::GLenum::GL_UNSIGNED_INT: { |
| const uint32_t* p = reinterpret_cast<const uint32_t*>(&indices[offset]); |
| for (uint32_t i = 0; i < count; i++) { v = max<uint32_t>(v, p[i]); } |
| break; |
| } |
| } |
| return v; |
| } |
| |
| inline int stateVariableSize(uint32_t v) { |
| switch (v) { |
| case GLenum::GL_ALIASED_LINE_WIDTH_RANGE: |
| return 2; |
| case GLenum::GL_ALIASED_POINT_SIZE_RANGE: |
| return 2; |
| case GLenum::GL_BLEND_COLOR: |
| return 4; |
| case GLenum::GL_COLOR_CLEAR_VALUE: |
| return 4; |
| case GLenum::GL_COLOR_WRITEMASK: |
| return 4; |
| case GLenum::GL_DEPTH_RANGE: |
| return 2; |
| case GLenum::GL_MAX_VIEWPORT_DIMS: |
| return 2; |
| case GLenum::GL_SCISSOR_BOX: |
| return 4; |
| case GLenum::GL_VIEWPORT: |
| return 4; |
| default: |
| return 1; |
| } |
| } |
| |
| inline int pixelSize(uint32_t format, uint32_t type) { |
| int num_components = 0; |
| switch (format) { |
| case GLenum::GL_ALPHA: |
| num_components = 1; |
| break; |
| case GLenum::GL_LUMINANCE: |
| num_components = 1; |
| break; |
| case GLenum::GL_LUMINANCE_ALPHA: |
| num_components = 2; |
| break; |
| case GLenum::GL_RED: |
| num_components = 1; |
| break; |
| case GLenum::GL_RED_INTEGER: |
| num_components = 1; |
| break; |
| case GLenum::GL_RG: |
| num_components = 2; |
| break; |
| case GLenum::GL_RG_INTEGER: |
| num_components = 2; |
| break; |
| case GLenum::GL_RGB: |
| num_components = 3; |
| break; |
| case GLenum::GL_RGB_INTEGER: |
| num_components = 3; |
| break; |
| case GLenum::GL_RGBA: |
| num_components = 4; |
| break; |
| case GLenum::GL_RGBA_INTEGER: |
| num_components = 4; |
| break; |
| case GLenum::GL_DEPTH_COMPONENT: |
| num_components = 1; |
| break; |
| case GLenum::GL_DEPTH_STENCIL: |
| num_components = 2; |
| break; |
| case GLenum::GL_STENCIL_INDEX: |
| num_components = 1; |
| break; |
| } |
| |
| switch(type) { |
| case GLenum::GL_UNSIGNED_BYTE: |
| return num_components * 1; |
| case GLenum::GL_BYTE: |
| return num_components * 1; |
| case GLenum::GL_UNSIGNED_SHORT: |
| return num_components * 2; |
| case GLenum::GL_SHORT: |
| return num_components * 2; |
| case GLenum::GL_UNSIGNED_INT: |
| return num_components * 4; |
| case GLenum::GL_INT: |
| return num_components * 4; |
| case GLenum::GL_HALF_FLOAT: |
| return num_components * 2; |
| case GLenum::GL_HALF_FLOAT_OES: |
| return num_components * 2; |
| case GLenum::GL_FLOAT: |
| return num_components * 4; |
| case GLenum::GL_UNSIGNED_SHORT_5_6_5: |
| return 2; |
| case GLenum::GL_UNSIGNED_SHORT_4_4_4_4: |
| return 2; |
| case GLenum::GL_UNSIGNED_SHORT_5_5_5_1: |
| return 2; |
| case GLenum::GL_UNSIGNED_INT_2_10_10_10_REV: |
| return 4; |
| case GLenum::GL_UNSIGNED_INT_10F_11F_11F_REV: |
| return 4; |
| case GLenum::GL_UNSIGNED_INT_5_9_9_9_REV: |
| return 4; |
| case GLenum::GL_UNSIGNED_INT_24_8: |
| return 4; |
| case GLenum::GL_FLOAT_32_UNSIGNED_INT_24_8_REV: |
| return 8; |
| default: |
| return 0; // TODO: Assert? |
| } |
| } |
| |
| inline void onGlError(std::shared_ptr<gapii::Context> ctx, GLenum_Error err) { |
| switch (err) { |
| case GLenum::GL_INVALID_ENUM: |
| GAPID_WARNING("Error calling %s: GL_INVALID_ENUM", mCurrentCommandName); |
| break; |
| case GLenum::GL_INVALID_VALUE: |
| GAPID_WARNING("Error calling %s: GL_INVALID_VALUE", mCurrentCommandName); |
| break; |
| case GLenum::GL_INVALID_OPERATION: |
| GAPID_WARNING("Error calling %s: GL_INVALID_OPERATION", mCurrentCommandName); |
| break; |
| case GLenum::GL_STACK_OVERFLOW: |
| GAPID_WARNING("Error calling %s: GL_STACK_OVERFLOW", mCurrentCommandName); |
| break; |
| case GLenum::GL_STACK_UNDERFLOW: |
| GAPID_WARNING("Error calling %s: GL_STACK_UNDERFLOW", mCurrentCommandName); |
| break; |
| case GLenum::GL_OUT_OF_MEMORY: |
| GAPID_WARNING("Error calling %s: GL_OUT_OF_MEMORY", mCurrentCommandName); |
| break; |
| case GLenum::GL_INVALID_FRAMEBUFFER_OPERATION: |
| GAPID_WARNING("Error calling %s: GL_INVALID_FRAMEBUFFER_OPERATION", mCurrentCommandName); |
| break; |
| case GLenum::GL_CONTEXT_LOST: |
| GAPID_WARNING("Error calling %s: GL_CONTEXT_LOST", mCurrentCommandName); |
| break; |
| default: |
| GAPID_WARNING("Error calling %s: %d", mCurrentCommandName, err); |
| break; |
| } |
| |
| if (ctx == nullptr) { |
| GAPID_WARNING("Error raised with no context. Aborting command."); |
| abort(); |
| return; |
| } |
| // If no current value then initialize, otherwise update if not GL_NO_ERROR |
| auto ret = mErrors.insert(std::make_pair(ctx->mIdentifier, err)); |
| bool inserted = ret.second; |
| if (!inserted) { |
| auto& value = ret.first->second; |
| if (value == GLenum::GL_NO_ERROR) { |
| // Per spec flag is only update if it is not set. |
| value = err; |
| } |
| } |
| } |
| |
| inline GLenum_Error getAndClearAnErrorFlag(std::shared_ptr<gapii::Context> ctx) { |
| if (ctx == nullptr) { |
| return GLenum::GL_INVALID_OPERATION; |
| } |
| // lookup the value, use GL_NO_ERROR as the default, clear the value. |
| auto it = mErrors.find(ctx->mIdentifier); |
| auto err = GLenum::GL_NO_ERROR; |
| if (it == mErrors.end()) { |
| return err; |
| } |
| std::swap(it->second, err); |
| return err; |
| } |