| /* |
| * Copyright 2016 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 GLIMP_GLES_DRAW_STATE_H_ |
| #define GLIMP_GLES_DRAW_STATE_H_ |
| |
| #include <algorithm> |
| #include <utility> |
| #include <vector> |
| |
| #include "glimp/egl/surface.h" |
| #include "glimp/gles/blend_state.h" |
| #include "glimp/gles/buffer.h" |
| #include "glimp/gles/cull_face_state.h" |
| #include "glimp/gles/framebuffer.h" |
| #include "glimp/gles/program.h" |
| #include "glimp/gles/sampler.h" |
| #include "glimp/gles/vertex_attribute.h" |
| #include "nb/rect.h" |
| #include "nb/ref_counted.h" |
| |
| namespace glimp { |
| namespace gles { |
| |
| // Types passed in as parameters to draw calls (like DrawArrays()) to |
| // describe the set of only enabled vertex attributes. |
| typedef std::vector<std::pair<unsigned int, VertexAttributeArray*> > |
| EnabledVertexAttributeList; |
| |
| // If a vertex attribute constant is specified (e.g. through a call to |
| // glVertexAttribXfv()) for a location, and the vertex attribute array is |
| // disabled at that location, then this constant value will be included into |
| // the draw state. |
| typedef std::vector<std::pair<unsigned int, VertexAttributeConstant*> > |
| ConstantVertexAttributeList; |
| |
| // Similar to EnabledVertexAttributeList, but lists only texture units with |
| // textures bound to them. |
| typedef std::vector<std::pair<unsigned int, Texture*> > EnabledTextureList; |
| |
| struct ViewportState { |
| ViewportState() : rect(-1, -1, -1, -1) {} |
| |
| nb::Rect<int> rect; |
| }; |
| |
| struct ScissorState { |
| ScissorState() : rect(-1, -1, -1, -1), enabled(false) {} |
| |
| nb::Rect<int> rect; |
| |
| bool enabled; |
| }; |
| |
| struct ClearColor { |
| // Setup initial values as defined in the specification. |
| // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glClearColor.xml |
| ClearColor() : red(0.0f), green(0.0f), blue(0.0f), alpha(0.0f) {} |
| ClearColor(float red, float green, float blue, float alpha) |
| : red(std::min(1.0f, std::max(0.0f, red))), |
| green(std::min(1.0f, std::max(0.0f, green))), |
| blue(std::min(1.0f, std::max(0.0f, blue))), |
| alpha(std::min(1.0f, std::max(0.0f, alpha))) {} |
| |
| // Clear color properties setup by calls to glClearColor(). |
| // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glClearColor.xml |
| float red; |
| float green; |
| float blue; |
| float alpha; |
| }; |
| |
| // Represents the state set by glColorMask(). |
| // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glColorMask.xml |
| struct ColorMask { |
| // Setup initial values as defined in the specification. |
| // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glColorMask.xml |
| ColorMask() : red(true), green(true), blue(true), alpha(true) {} |
| ColorMask(bool red, bool green, bool blue, bool alpha) |
| : red(red), green(green), blue(blue), alpha(alpha) {} |
| |
| bool red; |
| bool green; |
| bool blue; |
| bool alpha; |
| }; |
| |
| // This class is used to keep track of which uniform locations are dirty, or |
| // whether all of them are. |
| class DirtyUniforms { |
| public: |
| DirtyUniforms(); |
| |
| // Returns true if the uniform at |location| is dirty. |
| bool IsDirty(int location) const; |
| |
| // Returns true if any uniform is dirty. |
| bool AnyDirty() const; |
| |
| // Clears the dirty flag from all uniforms. |
| void ClearAll(); |
| |
| // Marks all uniforms as being dirty. |
| void MarkAll(); |
| |
| // Marks the uniform at |location| as being dirty. |
| void Mark(int location); |
| |
| private: |
| std::vector<int> uniforms_dirty_; |
| bool all_dirty_; |
| }; |
| |
| // The DrawState structure aggregates all GL state relevant to draw (or clear) |
| // commands. It will be modified as GL ES commands are issued, but it will |
| // only be propagated to the platform-specific implementations when draw (or |
| // clear) calls are made. A dirty flag is kept |
| struct DrawState { |
| // The color the next color buffer clear will clear to. |
| ClearColor clear_color; |
| |
| // Identifies which channels a draw (or clear) call is permitted to modify. |
| ColorMask color_mask; |
| |
| // The current surface that draw (or clear) commands will target. |
| egl::Surface* draw_surface; |
| |
| // The list of all active samplers that are available to the next draw call. |
| EnabledTextureList textures; |
| |
| // The list of vertex attribute binding information for the next draw call. |
| EnabledVertexAttributeList vertex_attributes; |
| ConstantVertexAttributeList constant_vertex_attributes; |
| |
| // The scissor rectangle. Draw calls should not modify pixels outside of |
| // this. |
| ScissorState scissor; |
| |
| // The viewport defines how normalized device coordinates should be |
| // transformed to screen pixel coordinates. |
| ViewportState viewport; |
| |
| // Defines how pixels produced by a draw call should be blended with the |
| // existing pixels in the output framebuffer. |
| BlendState blend_state; |
| |
| // Defines whether face culling is enabled, and upon which face if so. |
| CullFaceState cull_face_state; |
| |
| // The currently bound array buffer, set by calling |
| // glBindBuffer(GL_ARRAY_BUFFER). |
| nb::scoped_refptr<Buffer> array_buffer; |
| |
| // The currently bound element array buffer, set by calling |
| // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER). |
| nb::scoped_refptr<Buffer> element_array_buffer; |
| |
| // The currently in-use Program object, set by a call to glUseProgram(). |
| nb::scoped_refptr<Program> used_program; |
| |
| // The currently bound framebuffer. This is never NULL, even if the |
| // default framebuffer is bound, in which case |
| // framebuffer->color_attachment_surface() will be non-NULL and point to |
| // the draw surface specified through eglMakeCurrent(). |
| nb::scoped_refptr<Framebuffer> framebuffer; |
| }; |
| |
| // The dirty flags structure tracks which draw state members have been modified |
| // since the last draw call was made. This can be leveraged by implementations |
| // to avoid re-configurating draw state that has not changed. Implementations |
| // should manually set these flags to false after they have been processed. |
| struct DrawStateDirtyFlags { |
| DrawStateDirtyFlags() { MarkAll(); } |
| |
| void MarkAll() { |
| clear_color_dirty = true; |
| color_mask_dirty = true; |
| draw_surface_dirty = true; |
| textures_dirty = true; |
| vertex_attributes_dirty = true; |
| scissor_dirty = true; |
| viewport_dirty = true; |
| blend_state_dirty = true; |
| cull_face_dirty = true; |
| array_buffer_dirty = true; |
| element_array_buffer_dirty = true; |
| used_program_dirty = true; |
| framebuffer_dirty = true; |
| uniforms_dirty.MarkAll(); |
| } |
| |
| void MarkUsedProgram() { |
| used_program_dirty = true; |
| // Switching programs marks all uniforms, samplers and vertex attributes |
| // as being dirty as well, since they are all properties of the program. |
| vertex_attributes_dirty = true; |
| textures_dirty = true; |
| uniforms_dirty.MarkAll(); |
| } |
| |
| bool clear_color_dirty; |
| bool color_mask_dirty; |
| bool draw_surface_dirty; |
| bool textures_dirty; |
| bool vertex_attributes_dirty; |
| bool scissor_dirty; |
| bool viewport_dirty; |
| bool blend_state_dirty; |
| bool cull_face_dirty; |
| bool array_buffer_dirty; |
| bool element_array_buffer_dirty; |
| bool used_program_dirty; |
| bool framebuffer_dirty; |
| |
| // A list of uniform locations (within DrawState::used_program->uniforms()) |
| // whose values are dirty. |
| DirtyUniforms uniforms_dirty; |
| }; |
| |
| } // namespace gles |
| } // namespace glimp |
| |
| #endif // GLIMP_GLES_DRAW_STATE_H_ |