910e62b5创建于 1月15日历史提交
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is here so other GLES2 related files can have a common set of
// includes where appropriate.

#ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H_
#define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H_

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <string>

#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/numerics/safe_math.h"
#include "gpu/command_buffer/common/gles2_utils_export.h"

namespace gpu {
namespace gles2 {

// A 32-bit and 64-bit compatible way of converting a pointer to a
// 32-bit usigned integer, suitable to be stored in a GLuint.
inline uint32_t ToGLuint(const void* ptr) {
  return static_cast<uint32_t>(reinterpret_cast<size_t>(ptr));
}

// Returns the address of the first byte after a struct.
template <typename T>
const volatile void* AddressAfterStruct(const volatile T& pod) {
  return UNSAFE_TODO(reinterpret_cast<const volatile uint8_t*>(&pod) +
                     sizeof(pod));
}

// Returns the address of the frst byte after the struct or nullptr if size >
// immediate_data_size.
template <typename RETURN_TYPE, typename COMMAND_TYPE>
RETURN_TYPE GetImmediateDataAs(const volatile COMMAND_TYPE& pod,
                               uint32_t size,
                               uint32_t immediate_data_size) {
  return (size <= immediate_data_size)
             ? static_cast<RETURN_TYPE>(
                   const_cast<volatile void*>(AddressAfterStruct(pod)))
             : nullptr;
}

struct GLES2_UTILS_EXPORT PixelStoreParams {
  PixelStoreParams()
      : alignment(4),
        row_length(0),
        image_height(0),
        skip_pixels(0),
        skip_rows(0),
        skip_images(0) {
  }

  int32_t alignment;
  int32_t row_length;
  int32_t image_height;
  int32_t skip_pixels;
  int32_t skip_rows;
  int32_t skip_images;
};

// Utilties for GLES2 support.
class GLES2_UTILS_EXPORT GLES2Util {
 public:
  static const int kNumFaces = 6;

  // Bits returned by GetChannelsForFormat
  enum ChannelBits {
    kRed = 0x1,
    kGreen = 0x2,
    kBlue = 0x4,
    kAlpha = 0x8,
    kDepth = 0x10000,
    kStencil = 0x20000,

    kRGB = kRed | kGreen | kBlue,
    kRGBA = kRGB | kAlpha
  };

  struct EnumToString {
    uint32_t value;
    const char* name;
  };

  GLES2Util()
      : num_compressed_texture_formats_(0),
        num_shader_binary_formats_(0) {
  }

  int num_compressed_texture_formats() const {
    return num_compressed_texture_formats_;
  }

  void set_num_compressed_texture_formats(int num_compressed_texture_formats) {
    num_compressed_texture_formats_ = num_compressed_texture_formats;
  }

  int num_shader_binary_formats() const {
    return num_shader_binary_formats_;
  }

  void set_num_shader_binary_formats(int num_shader_binary_formats) {
    num_shader_binary_formats_ = num_shader_binary_formats;
  }

  // Gets the number of values a particular id will return when a glGet
  // function is called. If 0 is returned the id is invalid.
  int GLGetNumValuesReturned(int id) const;

  static uint32_t ElementsPerGroup(int format, int type);
  // Computes the size of a single group of elements from a format and type pair
  static uint32_t ComputeImageGroupSize(int format, int type);

  // Computes the size of an image row including alignment padding
  static bool ComputeImagePaddedRowSize(
      int width, int format, int type, int alignment,
      uint32_t* padded_row_size);

  // Computes the size of image data for TexImage2D and TexSubImage2D.
  // Optionally the unpadded and padded row sizes can be returned.
  static bool ComputeImageDataSizes(
      int width, int height, int depth, int format, int type,
      int alignment, uint32_t* size, uint32_t* opt_unpadded_row_size,
      uint32_t* opt_padded_row_size);

  // Similar to the above function, but taking into consideration all ES3
  // pixel pack/unpack parameters.
  // Optionally the skipped bytes in the beginning can be returned.
  // Note the returned |size| does NOT include |skip_size|.
  // TODO(zmo): merging ComputeImageDataSize and ComputeImageDataSizeES3.
  static bool ComputeImageDataSizesES3(
      int width, int height, int depth, int format, int type,
      const PixelStoreParams& params,
      uint32_t* size, uint32_t* opt_unpadded_row_size,
      uint32_t* opt_padded_row_size, uint32_t* opt_skip_size,
      uint32_t* opt_padding);

  static uint32_t RenderbufferBytesPerPixel(int format);

  static uint8_t StencilBitsPerPixel(int format);

  // Return the element's number of bytes.
  // For example, GL_FLOAT_MAT3 returns sizeof(GLfloat).
  static uint32_t GetElementSizeForUniformType(int type);
  // Return the number of elements.
  // For example, GL_FLOAT_MAT3 returns 9.
  static uint32_t GetElementCountForUniformType(int type);

  static uint32_t GetGLTypeSizeForTextures(uint32_t type);

  static uint32_t GetGLTypeSizeForBuffers(uint32_t type);

  static uint32_t GetGroupSizeForBufferType(uint32_t count, uint32_t type);

  static uint32_t GLErrorToErrorBit(uint32_t gl_error);

  static uint32_t GLErrorBitToGLError(uint32_t error_bit);

  static uint32_t IndexToGLFaceTarget(int index);

  static size_t GLTargetToFaceIndex(uint32_t target);
  static uint32_t GLFaceTargetToTextureTarget(uint32_t target);

  static uint32_t GetGLReadPixelsImplementationFormat(uint32_t internal_format,
                                                      uint32_t texture_type,
                                                      bool supports_bgra);

  static uint32_t GetGLReadPixelsImplementationType(
      uint32_t internal_format, uint32_t texture_type);

  // Returns a bitmask for the channels the given format supports.
  // See ChannelBits.
  static uint32_t GetChannelsForFormat(int format);

  // Returns a bitmask for the channels the given attachment type needs.
  static uint32_t GetChannelsNeededForAttachmentType(
      int type, uint32_t max_color_attachments);

  // Return true if value is neither a power of two nor zero.
  static bool IsNPOT(uint32_t value) {
    return (value & (value - 1)) != 0;
  }

  // Return true if value is a power of two or zero.
  static bool IsPOT(uint32_t value) {
    return (value & (value - 1)) == 0;
  }

  static std::string GetStringEnum(uint32_t value);
  static std::string GetStringBool(uint32_t value);
  static std::string GetStringError(uint32_t value);

  static uint32_t CalcClearBufferivDataCount(int buffer);
  static uint32_t CalcClearBufferfvDataCount(int buffer);
  static uint32_t CalcClearBufferuivDataCount(int buffer);

  constexpr static uint32_t
  CalcFramebufferPixelLocalClearValueufvANGLEDataCount(int plane) {
    return 4;
  }
  constexpr static uint32_t
  CalcFramebufferPixelLocalClearValueuivANGLEDataCount(int plane) {
    return 4;
  }
  constexpr static uint32_t
  CalcFramebufferPixelLocalClearValueuuivANGLEDataCount(int plane) {
    return 4;
  }

  static void MapUint64ToTwoUint32(
      uint64_t v64, uint32_t* v32_0, uint32_t* v32_1);
  static uint64_t MapTwoUint32ToUint64(uint32_t v32_0, uint32_t v32_1);

  static uint32_t MapBufferTargetToBindingEnum(uint32_t target);

  static bool IsUnsignedIntegerFormat(uint32_t internal_format);
  static bool IsSignedIntegerFormat(uint32_t internal_format);
  static bool IsIntegerFormat(uint32_t internal_format);
  static bool IsFloatFormat(uint32_t internal_format);
  static bool IsFloat32Format(uint32_t internal_format);
  static uint32_t ConvertToSizedFormat(uint32_t format, uint32_t type);
  static bool IsSizedColorFormat(uint32_t internal_format);

  // Infer color encoding from internalformat
  static int GetColorEncodingFromInternalFormat(uint32_t internalformat);

  static void GetColorFormatComponentSizes(
      uint32_t internal_format, uint32_t type, int* r, int* g, int* b, int* a);

  // Computes the data size for certain gl commands like glUniform.
  template <typename VALUE_TYPE, unsigned int ELEMENTS_PER_UNIT>
  static bool ComputeDataSize(uint32_t count, uint32_t* dst) {
    constexpr uint32_t element_size = sizeof(VALUE_TYPE) * ELEMENTS_PER_UNIT;
    return base::CheckMul(count, element_size).AssignIfValid(dst);
  }

#include "gpu/command_buffer/common/gles2_cmd_utils_autogen.h"

 private:
  static std::string GetQualifiedEnumString(
      const EnumToString* table, size_t count, uint32_t value);

  static bool ComputeImageRowSizeHelper(int width,
                                        uint32_t bytes_per_group,
                                        int alignment,
                                        uint32_t* rt_unpadded_row_size,
                                        uint32_t* rt_padded_row_size,
                                        uint32_t* rt_padding);

  int num_compressed_texture_formats_;
  int num_shader_binary_formats_;
};

class GLES2_UTILS_EXPORT GLSLArrayName {
 public:
  explicit GLSLArrayName(const std::string& name);

  GLSLArrayName(const GLSLArrayName&) = delete;
  GLSLArrayName& operator=(const GLSLArrayName&) = delete;

  // Returns true if the string is an array reference.
  bool IsArrayName() const { return element_index_ >= 0; }
  // Returns the name with the possible last array index specifier removed.
  std::string base_name() const {
    DCHECK(IsArrayName());
    return base_name_;
  }
  // Returns the element index of a name which references an array element.
  int element_index() const {
    DCHECK(IsArrayName());
    return element_index_;
  }

 private:
  std::string base_name_;
  int element_index_;
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H_