| // Copyright 2017 Google Inc. All Rights Reserved. |
| // |
| // 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. |
| |
| #ifndef COBALT_RENDERER_RASTERIZER_EGL_TEXTURED_MESH_RENDERER_H_ |
| #define COBALT_RENDERER_RASTERIZER_EGL_TEXTURED_MESH_RENDERER_H_ |
| |
| #include <map> |
| #include <string> |
| #include <tuple> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/optional.h" |
| #include "cobalt/math/rect.h" |
| #include "cobalt/renderer/backend/egl/graphics_context.h" |
| #include "cobalt/renderer/backend/egl/texture.h" |
| #include "third_party/glm/glm/mat4x4.hpp" |
| |
| namespace cobalt { |
| namespace renderer { |
| namespace rasterizer { |
| namespace egl { |
| |
| // Helper class to render textured meshes. The class is centered around the |
| // public method RenderVBO(), which can be used to render an arbitrary GLES2 |
| // vertex buffer object (where each vertex has a 3-float position and a |
| // 2-float texture coordinate), with a specified texture applied to it. |
| class TexturedMeshRenderer { |
| public: |
| explicit TexturedMeshRenderer(backend::GraphicsContextEGL* graphics_context); |
| ~TexturedMeshRenderer(); |
| |
| // The Image structure acts as an interface for describing an image, which |
| // in the case of YUV formats, may be composed of multiple textures. |
| struct Image { |
| enum Type { |
| // YUV BT709 image, where the Y component is on one plane and the UV |
| // components are on a second plane. NV12 would for example choose |
| // this format type. |
| YUV_2PLANE_BT709, |
| // YUV BT709 image where the Y, U and V components are all on different |
| // textures. |
| YUV_3PLANE_BT709, |
| // 1 texture is used that contains RGBA pixels. |
| RGBA, |
| // 1 texture plane is used where Y is sampled twice for each UV sample |
| // (horizontally). |
| YUV_UYVY_422_BT709, |
| }; |
| |
| struct Texture { |
| const backend::TextureEGL* texture; |
| math::Rect content_region; |
| }; |
| |
| // Returns the number of valid textures in this image, based on its format. |
| int num_textures() const { |
| switch (type) { |
| case YUV_2PLANE_BT709: |
| return 2; |
| case YUV_3PLANE_BT709: |
| return 3; |
| case RGBA: |
| case YUV_UYVY_422_BT709: |
| return 1; |
| default: |
| NOTREACHED(); |
| } |
| return 0; |
| } |
| |
| Type type; |
| Texture textures[3]; |
| }; |
| |
| // A context must be current before this method is called. Before calling |
| // this function, please configure glViewport() and glScissor() as desired. |
| // The content region indicates which source rectangle of the input texture |
| // should be used (i.e. the VBO's texture coordinates will be transformed to |
| // lie within this rectangle). |
| void RenderVBO(uint32 vbo, int num_vertices, uint32 mode, const Image& image, |
| const glm::mat4& mvp_transform); |
| |
| // This method will call into RenderVBO(), so the comments pertaining to that |
| // method also apply to this method. This method renders with vertex |
| // positions (-1, -1) -> (1, 1), so it will occupy the entire viewport |
| // specified by glViewport(). |
| void RenderQuad(const Image& image, const glm::mat4& mvp_transform); |
| |
| private: |
| struct TextureInfo { |
| TextureInfo(const std::string& name, const std::string& components) |
| : name(name), components(components) {} |
| |
| std::string name; |
| std::string components; |
| }; |
| struct ProgramInfo { |
| int32 mvp_transform_uniform; |
| int32 texcoord_scale_translate_uniforms[3]; |
| int32 texture_uniforms[3]; |
| int32 texture_size_uniforms[3]; |
| uint32 gl_program_id; |
| }; |
| // We key each program off of their GL texture type and image type. |
| typedef std::tuple<uint32, Image::Type, base::optional<int32> > CacheKey; |
| typedef std::map<CacheKey, ProgramInfo> ProgramCache; |
| |
| uint32 GetQuadVBO(); |
| ProgramInfo GetBlitProgram(const Image& image); |
| |
| static ProgramInfo MakeBlitProgram(const float* color_matrix, |
| const std::vector<TextureInfo>& textures, |
| uint32 blit_fragment_shader); |
| |
| static uint32 CreateFragmentShader(uint32 texture_target, |
| const std::vector<TextureInfo>& textures); |
| static uint32 CreateVertexShader(const std::vector<TextureInfo>& textures); |
| |
| // UYVY textures need a special fragment shader to handle the unique aspect |
| // of applying bilinear filtering within a texel between the two Y values. |
| static uint32 CreateUYVYFragmentShader(uint32 texture_target, |
| int32 texture_wrap_s); |
| |
| backend::GraphicsContextEGL* graphics_context_; |
| |
| // Since different texture targets can warrant different shaders/programs, |
| // we keep a map of blit programs for each texture target, and initialize |
| // them lazily. |
| ProgramCache blit_program_cache_; |
| |
| static const int kBlitPositionAttribute = 0; |
| static const int kBlitTexcoordAttribute = 1; |
| |
| base::optional<uint32> quad_vbo_; |
| }; |
| |
| } // namespace egl |
| } // namespace rasterizer |
| } // namespace renderer |
| } // namespace cobalt |
| |
| #endif // COBALT_RENDERER_RASTERIZER_EGL_TEXTURED_MESH_RENDERER_H_ |