| /* |
| * Copyright (C) 2016 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. |
| */ |
| |
| #include "gles_spy.h" |
| #include "gles_constants.h" |
| |
| namespace gapii { |
| |
| using namespace gapii::GLenum; |
| |
| // Populate the specified GLES spy object with initial "constant" state needed |
| // to build a valid context object. This is used to simulate eglMakeCurrent or |
| // one of its cousins. |
| void GlesSpy::setContextInfo( |
| int32_t backbuffer_width, int32_t backbuffer_height, |
| uint32_t backbuffer_color_fmt, uint32_t backbuffer_depth_fmt, |
| uint32_t backbuffer_stencil_fmt, bool reset_viewport_scissor, |
| bool preserve_buffers_on_swap) { |
| |
| setContextInfo( |
| backbuffer_width, backbuffer_height, |
| backbuffer_color_fmt, backbuffer_depth_fmt, |
| backbuffer_stencil_fmt, reset_viewport_scissor, |
| preserve_buffers_on_swap, kGLESConstantDescs); |
| } |
| |
| void GlesSpy::setContextInfo( |
| int32_t backbuffer_width, int32_t backbuffer_height, |
| uint32_t backbuffer_color_fmt, uint32_t backbuffer_depth_fmt, |
| uint32_t backbuffer_stencil_fmt, bool reset_viewport_scissor, |
| bool preserve_buffers_on_swap, const ConstantDesc* constantDescs) { |
| |
| struct Constants { |
| void add(uint32_t name, void* value, uint32_t size, int alignment) { |
| while(data.size() % alignment != 0) { |
| data.push_back(0); |
| } |
| names.push_back(name); |
| offsets.push_back(data.size()); |
| sizes.push_back(size); |
| uint8_t* v = reinterpret_cast<uint8_t*>(value); |
| data.insert(data.end(), v, v + size); |
| } |
| |
| std::vector<uint32_t> names; // GLenum |
| std::vector<uint32_t> offsets; |
| std::vector<uint32_t> sizes; |
| std::vector<uint8_t> data; |
| } constants; |
| |
| std::shared_ptr<Context> ctx = Contexts[CurrentThread]; |
| while (mImports.glGetError() != GL_NO_ERROR) { } // clear errors |
| |
| GLint major_version = 0; |
| mImports.glGetIntegerv(GL_MAJOR_VERSION, &major_version); |
| bool is_gles_30_or_newer = (mImports.glGetError() == GL_NO_ERROR) && (major_version >= 3); |
| |
| // Record implementation dependent constants from glGetString. |
| uint32_t strings[] { GL_EXTENSIONS, GL_RENDERER, GL_SHADING_LANGUAGE_VERSION, GL_VENDOR, GL_VERSION }; |
| for (uint32_t name : strings) { |
| char* value = reinterpret_cast<char*>(mImports.glGetString(name)); |
| if (mImports.glGetError() == GL_NO_ERROR) { |
| if (value != nullptr) { |
| constants.add(name, value, strlen(value), 1); |
| constants.data.push_back(0); // add null-terminator. |
| } else { |
| GAPID_WARNING("glGetString(%u) returned null", name); |
| } |
| } |
| } |
| |
| // Record implementation dependent constants from glGetShaderPrecisionFormat. |
| uint32_t precisions[] { GL_LOW_FLOAT, GL_MEDIUM_FLOAT, GL_HIGH_FLOAT, GL_LOW_INT, GL_MEDIUM_INT, GL_HIGH_INT }; |
| for (uint32_t name : precisions) { |
| GLint values[6]; |
| mImports.glGetShaderPrecisionFormat(GL_VERTEX_SHADER, name, &values[0], &values[2]); |
| mImports.glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, name, &values[3], &values[5]); |
| if (mImports.glGetError() == GL_NO_ERROR) { |
| constants.add(name, values, sizeof(values), sizeof(GLint)); |
| } |
| } |
| |
| // Record implementation dependent constants from glGet* family of methods. |
| std::vector<uint8_t> buffer; |
| for (const ConstantDesc* desc = constantDescs; desc->name != 0; desc++) { |
| if (GetConstant(mImports, is_gles_30_or_newer, desc, &buffer)) { |
| int alignment = GetSizeOfGLType(desc->type); |
| constants.add(desc->name, buffer.data(), buffer.size(), alignment); |
| } |
| } |
| |
| contextInfo(constants.names.size(), |
| constants.names.data(), |
| constants.offsets.data(), |
| constants.sizes.data(), |
| constants.data.data(), |
| backbuffer_width, backbuffer_height, |
| backbuffer_color_fmt, backbuffer_depth_fmt, |
| backbuffer_stencil_fmt, reset_viewport_scissor, |
| preserve_buffers_on_swap); |
| } |
| |
| } // namespace gapii |