// Copyright 2015 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_BACKEND_EGL_TEXTURE_DATA_H_
#define COBALT_RENDERER_BACKEND_EGL_TEXTURE_DATA_H_

#include <GLES2/gl2.h>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/math/size.h"

namespace cobalt {
namespace renderer {
namespace backend {

class GraphicsContextEGL;

// All TextureDataEGL subclasses must also implement ConvertToTexture() to
// convert their pixel buffer data to a GL texture object and return the handle
// to it.  After this method is called, the TextureData should be considered
// invalid.
class TextureDataEGL {
 public:
  virtual ~TextureDataEGL() {}

  virtual GLuint ConvertToTexture(GraphicsContextEGL* graphics_context,
                                  bool bgra_supported) = 0;
  // Returns information about the kind of data this TextureData is
  // intended to store.
  virtual const math::Size& GetSize() const = 0;
  virtual GLenum GetFormat() const = 0;

  virtual int GetPitchInBytes() const = 0;

  // Returns a pointer to the image data so that one can set pixel data as
  // necessary.
  virtual uint8_t* GetMemory() = 0;

  // Returns true if there was an error during object construction.
  virtual bool CreationError() = 0;
};

// Similar to TextureDataEGL::ConvertToTexture(), though this creates a texture
// without invalidating the RawTextureMemoryEGL object, so that multiple
// textures may be created through this data.
class RawTextureMemoryEGL {
 public:
  virtual ~RawTextureMemoryEGL() {}

  // Returns the allocated size of the texture memory.
  virtual size_t GetSizeInBytes() const = 0;

  // Returns a CPU-accessible pointer to the allocated memory.
  virtual uint8_t* GetMemory() = 0;

  virtual GLuint CreateTexture(GraphicsContextEGL* graphics_context,
                               intptr_t offset, const math::Size& size,
                               GLenum format, int pitch_in_bytes,
                               bool bgra_supported) const = 0;

 protected:
  // Called within ConstRawTextureMemoryEGL's constructor to indicate that we
  // are
  // done modifying the contained data and that it should be frozen and made
  // immutable at that point.  For example, if using GLES3 PBOs, this would be a
  // good time to call glUnmapBuffer() on the data.
  virtual void MakeConst() = 0;

  friend class ConstRawTextureMemoryEGL;
};

// In order to allow the GPU to access raw texture memory, it must first be
// made immutable by constructing a ConstRawTextureMemoryEGL object from a
// RawTextureMemoryEGL object.  This is so that we can guarantee that when the
// GPU starts reading it, the CPU will not be writing to it and possibly
// creating a race condition.
class ConstRawTextureMemoryEGL
    : public base::RefCountedThreadSafe<ConstRawTextureMemoryEGL> {
 public:
  explicit ConstRawTextureMemoryEGL(
      scoped_ptr<RawTextureMemoryEGL> raw_texture_memory)
      : raw_texture_memory_(raw_texture_memory.Pass()) {
    raw_texture_memory_->MakeConst();
  }

  const RawTextureMemoryEGL& raw_texture_memory() const {
    return *raw_texture_memory_;
  }

  size_t GetSizeInBytes() const {
    return raw_texture_memory_->GetSizeInBytes();
  }

 private:
  virtual ~ConstRawTextureMemoryEGL() {}

  scoped_ptr<RawTextureMemoryEGL> raw_texture_memory_;

  friend class base::RefCountedThreadSafe<ConstRawTextureMemoryEGL>;
};

void SetupInitialTextureParameters();

}  // namespace backend
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_BACKEND_EGL_TEXTURE_DATA_H_
