blob: 0f65a59538cdd7a3129570c8a559e962f81e7c47 [file] [log] [blame]
// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_OUTPUT_SHADER_H_
#define CC_OUTPUT_SHADER_H_
#include <string>
#include "base/logging.h"
#include "base/macros.h"
#include "cc/base/cc_export.h"
namespace gfx {
class ColorTransform;
class Point;
class Size;
}
namespace gpu {
namespace gles2 {
class GLES2Interface;
}
}
namespace cc {
enum TexCoordPrecision {
TEX_COORD_PRECISION_NA = 0,
TEX_COORD_PRECISION_MEDIUM = 1,
TEX_COORD_PRECISION_HIGH = 2,
};
// Texture coordinate sources for the vertex shader.
enum TexCoordSource {
// Vertex shader does not populate a texture coordinate.
TEX_COORD_SOURCE_NONE,
// Texture coordinate is set to the untransformed position.
TEX_COORD_SOURCE_POSITION,
// Texture coordinate has its own attribute.
TEX_COORD_SOURCE_ATTRIBUTE,
};
// Texture coordinate transformation modes for the vertex shader.
enum TexCoordTransform {
// Texture coordinates are not transformed.
TEX_COORD_TRANSFORM_NONE,
// Texture coordinates are transformed by a uniform vec4, scaling by zw and
// then translating by xy.
TEX_COORD_TRANSFORM_VEC4,
// Same as the above, but add vec2(0.5) to the texture coordinate first.
TEX_COORD_TRANSFORM_TRANSLATED_VEC4,
// Texture coordiantes are transformed by a uniform mat4.
TEX_COORD_TRANSFORM_MATRIX,
};
// Position source for the vertex shader.
enum PositionSource {
// The position is read directly from the position attribute.
POSITION_SOURCE_ATTRIBUTE,
// The position is read by attribute index into a uniform array for xy, and
// getting zw from the attribute.
POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM,
};
enum AAMode {
NO_AA = 0,
USE_AA = 1,
};
enum SwizzleMode {
NO_SWIZZLE = 0,
DO_SWIZZLE = 1,
};
enum PremultipliedAlphaMode {
PREMULTIPLIED_ALPHA = 0,
NON_PREMULTIPLIED_ALPHA = 1,
};
enum SamplerType {
SAMPLER_TYPE_NA = 0,
SAMPLER_TYPE_2D = 1,
SAMPLER_TYPE_2D_RECT = 2,
SAMPLER_TYPE_EXTERNAL_OES = 3,
};
enum BlendMode {
BLEND_MODE_NONE,
BLEND_MODE_NORMAL,
BLEND_MODE_DESTINATION_IN,
BLEND_MODE_SCREEN,
BLEND_MODE_OVERLAY,
BLEND_MODE_DARKEN,
BLEND_MODE_LIGHTEN,
BLEND_MODE_COLOR_DODGE,
BLEND_MODE_COLOR_BURN,
BLEND_MODE_HARD_LIGHT,
BLEND_MODE_SOFT_LIGHT,
BLEND_MODE_DIFFERENCE,
BLEND_MODE_EXCLUSION,
BLEND_MODE_MULTIPLY,
BLEND_MODE_HUE,
BLEND_MODE_SATURATION,
BLEND_MODE_COLOR,
BLEND_MODE_LUMINOSITY,
LAST_BLEND_MODE = BLEND_MODE_LUMINOSITY
};
enum InputColorSource {
// This includes RGB and RGBA textures.
INPUT_COLOR_SOURCE_RGBA_TEXTURE,
// This includes Y and either UV or U-and-V textures.
INPUT_COLOR_SOURCE_YUV_TEXTURES,
// A solid color specified as a uniform value.
INPUT_COLOR_SOURCE_UNIFORM,
};
enum UVTextureMode {
// Shader does not use YUV textures.
UV_TEXTURE_MODE_NA,
// UV plane is a single texture.
UV_TEXTURE_MODE_UV,
// U and V planes have separate textures.
UV_TEXTURE_MODE_U_V,
};
enum YUVAlphaTextureMode {
YUV_ALPHA_TEXTURE_MODE_NA,
YUV_NO_ALPHA_TEXTURE,
YUV_HAS_ALPHA_TEXTURE,
};
enum ColorConversionMode {
// No color conversion is performed.
COLOR_CONVERSION_MODE_NONE,
// Conversion is done directly from input RGB space (or YUV space if
// applicable) to output RGB space, via a 3D texture represented as a 2D
// texture.
COLOR_CONVERSION_MODE_LUT,
// Conversion is done analytically in the shader.
COLOR_CONVERSION_MODE_SHADER,
};
// TODO(ccameron): Merge this with BlendMode.
enum FragColorMode {
FRAG_COLOR_MODE_DEFAULT,
FRAG_COLOR_MODE_OPAQUE,
FRAG_COLOR_MODE_APPLY_BLEND_MODE,
};
enum MaskMode {
NO_MASK = 0,
HAS_MASK = 1,
};
// Note: The highp_threshold_cache must be provided by the caller to make
// the caching multi-thread/context safe in an easy low-overhead manner.
// The caller must make sure to clear highp_threshold_cache to 0, so it can be
// reinitialized, if a new or different context is used.
CC_EXPORT TexCoordPrecision
TexCoordPrecisionRequired(gpu::gles2::GLES2Interface* context,
int* highp_threshold_cache,
int highp_threshold_min,
const gfx::Point& max_coordinate);
CC_EXPORT TexCoordPrecision TexCoordPrecisionRequired(
gpu::gles2::GLES2Interface* context,
int *highp_threshold_cache,
int highp_threshold_min,
const gfx::Size& max_size);
class VertexShader {
public:
VertexShader();
void Init(gpu::gles2::GLES2Interface* context,
unsigned program,
int* base_uniform_index);
std::string GetShaderString() const;
protected:
friend class Program;
// Use arrays of uniforms for matrix, texTransform, and opacity.
bool use_uniform_arrays_ = false;
PositionSource position_source_ = POSITION_SOURCE_ATTRIBUTE;
TexCoordSource tex_coord_source_ = TEX_COORD_SOURCE_NONE;
TexCoordTransform tex_coord_transform_ = TEX_COORD_TRANSFORM_NONE;
// Used only with TEX_COORD_TRANSFORM_VEC4.
int vertex_tex_transform_location_ = -1;
// Used only with TEX_COORD_TRANSFORM_MATRIX.
int tex_matrix_location_ = -1;
// Uniforms for YUV textures.
bool is_ya_uv_ = false;
int ya_tex_scale_location_ = -1;
int ya_tex_offset_location_ = -1;
int uv_tex_scale_location_ = -1;
int uv_tex_offset_location_ = -1;
// Matrix to transform the position.
bool has_matrix_ = false;
int matrix_location_ = -1;
// Used only with POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM.
int quad_location_ = -1;
// Extra dummy variables to work around bugs on Android.
// TODO(ccameron): This is likley unneeded cargo-culting.
// http://crbug.com/240602
bool has_dummy_variables_ = false;
bool has_vertex_opacity_ = false;
int vertex_opacity_location_ = -1;
AAMode aa_mode_ = NO_AA;
int viewport_location_ = -1;
int edge_location_ = -1;
};
class FragmentShader {
public:
virtual void Init(gpu::gles2::GLES2Interface* context,
unsigned program,
int* base_uniform_index);
std::string GetShaderString() const;
protected:
FragmentShader();
virtual std::string GetShaderSource() const;
bool has_blend_mode() const { return blend_mode_ != BLEND_MODE_NONE; }
std::string SetBlendModeFunctions(const std::string& shader_string) const;
// Settings that are modified by sub-classes.
AAMode aa_mode_ = NO_AA;
bool has_varying_alpha_ = false;
SwizzleMode swizzle_mode_ = NO_SWIZZLE;
PremultipliedAlphaMode premultiply_alpha_mode_ = PREMULTIPLIED_ALPHA;
FragColorMode frag_color_mode_ = FRAG_COLOR_MODE_DEFAULT;
InputColorSource input_color_type_ = INPUT_COLOR_SOURCE_RGBA_TEXTURE;
// Used only if |blend_mode_| is not BLEND_MODE_NONE.
int backdrop_location_ = -1;
int original_backdrop_location_ = -1;
int backdrop_rect_location_ = -1;
// Used only if |input_color_type_| is INPUT_COLOR_SOURCE_RGBA_TEXTURE.
bool has_rgba_fragment_tex_transform_ = false;
int sampler_location_ = -1;
int fragment_tex_transform_location_ = -1;
// Always use sampler2D and texture2D for the RGBA texture, regardless of the
// specified SamplerType.
// TODO(ccameron): Change GLRenderer to always specify the correct
// SamplerType.
bool ignore_sampler_type_ = false;
// Used only if |input_color_type_| is INPUT_COLOR_SOURCE_UNIFORM.
int color_location_ = -1;
MaskMode mask_mode_ = NO_MASK;
int mask_sampler_location_ = -1;
int mask_tex_coord_scale_location_ = -1;
int mask_tex_coord_offset_location_ = -1;
bool has_color_matrix_ = false;
int color_matrix_location_ = -1;
int color_offset_location_ = -1;
bool has_uniform_alpha_ = false;
int alpha_location_ = -1;
bool has_background_color_ = false;
int background_color_location_ = -1;
TexCoordPrecision tex_coord_precision_ = TEX_COORD_PRECISION_NA;
SamplerType sampler_type_ = SAMPLER_TYPE_NA;
BlendMode blend_mode_ = BLEND_MODE_NONE;
bool mask_for_background_ = false;
// YUV-only parameters.
YUVAlphaTextureMode yuv_alpha_texture_mode_ = YUV_ALPHA_TEXTURE_MODE_NA;
UVTextureMode uv_texture_mode_ = UV_TEXTURE_MODE_UV;
ColorConversionMode color_conversion_mode_ = COLOR_CONVERSION_MODE_NONE;
const gfx::ColorTransform* color_transform_ = nullptr;
// YUV uniform locations.
int y_texture_location_ = -1;
int u_texture_location_ = -1;
int v_texture_location_ = -1;
int uv_texture_location_ = -1;
int a_texture_location_ = -1;
int ya_clamp_rect_location_ = -1;
int uv_clamp_rect_location_ = -1;
// The resource offset and multiplier to adjust for bit depth.
int resource_multiplier_location_ = -1;
int resource_offset_location_ = -1;
// LUT YUV to color-converted RGB.
int lut_texture_location_ = -1;
int lut_size_location_ = -1;
private:
friend class Program;
std::string GetHelperFunctions() const;
std::string GetBlendFunction() const;
std::string GetBlendFunctionBodyForAlpha() const;
std::string GetBlendFunctionBodyForRGB() const;
DISALLOW_COPY_AND_ASSIGN(FragmentShader);
};
} // namespace cc
#endif // CC_OUTPUT_SHADER_H_