// Copyright 2014 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.

#include "cc/resources/texture_uploader.h"

#include <algorithm>
#include <vector>

#include "base/debug/trace_event.h"
#include "base/metrics/histogram.h"
#include "cc/base/util.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/resource.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/vector2d.h"

using gpu::gles2::GLES2Interface;

namespace {

// How many previous uploads to use when predicting future throughput.
static const size_t kUploadHistorySizeMax = 1000;
static const size_t kUploadHistorySizeInitial = 100;

// Global estimated number of textures per second to maintain estimates across
// subsequent instances of TextureUploader.
// More than one thread will not access this variable, so we do not need to
// synchronize access.
static const double kDefaultEstimatedTexturesPerSecond = 48.0 * 60.0;

// Flush interval when performing texture uploads.
static const size_t kTextureUploadFlushPeriod = 4;

}  // anonymous namespace

namespace cc {

TextureUploader::Query::Query(GLES2Interface* gl)
    : gl_(gl),
      query_id_(0),
      value_(0),
      has_value_(false),
      is_non_blocking_(false) {
  gl_->GenQueriesEXT(1, &query_id_);
}

TextureUploader::Query::~Query() { gl_->DeleteQueriesEXT(1, &query_id_); }

void TextureUploader::Query::Begin() {
  has_value_ = false;
  is_non_blocking_ = false;
  gl_->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query_id_);
}

void TextureUploader::Query::End() {
  gl_->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
}

bool TextureUploader::Query::IsPending() {
  unsigned available = 1;
  gl_->GetQueryObjectuivEXT(
      query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  return !available;
}

unsigned TextureUploader::Query::Value() {
  if (!has_value_) {
    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_);
    has_value_ = true;
  }
  return value_;
}

TextureUploader::TextureUploader(GLES2Interface* gl)
    : gl_(gl),
      num_blocking_texture_uploads_(0),
      sub_image_size_(0),
      num_texture_uploads_since_last_flush_(0) {
  for (size_t i = kUploadHistorySizeInitial; i > 0; i--)
    textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond);
}

TextureUploader::~TextureUploader() {}

size_t TextureUploader::NumBlockingUploads() {
  ProcessQueries();
  return num_blocking_texture_uploads_;
}

void TextureUploader::MarkPendingUploadsAsNonBlocking() {
  for (ScopedPtrDeque<Query>::iterator it = pending_queries_.begin();
       it != pending_queries_.end();
       ++it) {
    if ((*it)->is_non_blocking())
      continue;

    num_blocking_texture_uploads_--;
    (*it)->mark_as_non_blocking();
  }

  DCHECK(!num_blocking_texture_uploads_);
}

double TextureUploader::EstimatedTexturesPerSecond() {
  ProcessQueries();

  // Use the median as our estimate.
  std::multiset<double>::iterator median = textures_per_second_history_.begin();
  std::advance(median, textures_per_second_history_.size() / 2);
  return *median;
}

void TextureUploader::BeginQuery() {
  // Check to see if any of the pending queries are free before allocating a
  // new one. If this is not done, queries may be allocated without bound.
  // http://crbug.com/398072
  if (available_queries_.empty())
    ProcessQueries();

  if (available_queries_.empty())
    available_queries_.push_back(Query::Create(gl_));

  available_queries_.front()->Begin();
}

void TextureUploader::EndQuery() {
  available_queries_.front()->End();
  pending_queries_.push_back(available_queries_.take_front());
  num_blocking_texture_uploads_++;
}

void TextureUploader::Upload(const uint8* image,
                             const gfx::Rect& image_rect,
                             const gfx::Rect& source_rect,
                             gfx::Vector2d dest_offset,
                             ResourceFormat format,
                             const gfx::Size& size) {
  CHECK(image_rect.Contains(source_rect));

  bool is_full_upload = dest_offset.IsZero() && source_rect.size() == size;

  if (is_full_upload)
    BeginQuery();

  if (format == ETC1) {
    // ETC1 does not support subimage uploads.
    DCHECK(is_full_upload);
    UploadWithTexImageETC1(image, size);
  } else {
    UploadWithMapTexSubImage(
        image, image_rect, source_rect, dest_offset, format);
  }

  if (is_full_upload)
    EndQuery();

  num_texture_uploads_since_last_flush_++;
  if (num_texture_uploads_since_last_flush_ >= kTextureUploadFlushPeriod)
    Flush();
}

void TextureUploader::Flush() {
  if (!num_texture_uploads_since_last_flush_)
    return;

  gl_->ShallowFlushCHROMIUM();

  num_texture_uploads_since_last_flush_ = 0;
}

void TextureUploader::ReleaseCachedQueries() {
  ProcessQueries();
  available_queries_.clear();
}

void TextureUploader::UploadWithTexSubImage(const uint8* image,
                                            const gfx::Rect& image_rect,
                                            const gfx::Rect& source_rect,
                                            gfx::Vector2d dest_offset,
                                            ResourceFormat format) {
  TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImage");

  // Early-out if this is a no-op, and assert that |image| be valid if this is
  // not a no-op.
  if (source_rect.IsEmpty())
    return;
  DCHECK(image);

  // Offset from image-rect to source-rect.
  gfx::Vector2d offset(source_rect.origin() - image_rect.origin());

  const uint8* pixel_source;
  unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
  // Use 4-byte row alignment (OpenGL default) for upload performance.
  // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
  unsigned upload_image_stride =
      RoundUp(bytes_per_pixel * source_rect.width(), 4u);

  if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
      !offset.x()) {
    pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()];
  } else {
    size_t needed_size = upload_image_stride * source_rect.height();
    if (sub_image_size_ < needed_size) {
      sub_image_.reset(new uint8[needed_size]);
      sub_image_size_ = needed_size;
    }
    // Strides not equal, so do a row-by-row memcpy from the
    // paint results into a temp buffer for uploading.
    for (int row = 0; row < source_rect.height(); ++row)
      memcpy(&sub_image_[upload_image_stride * row],
             &image[bytes_per_pixel *
                    (offset.x() + (offset.y() + row) * image_rect.width())],
             source_rect.width() * bytes_per_pixel);

    pixel_source = &sub_image_[0];
  }

  gl_->TexSubImage2D(GL_TEXTURE_2D,
                     0,
                     dest_offset.x(),
                     dest_offset.y(),
                     source_rect.width(),
                     source_rect.height(),
                     GLDataFormat(format),
                     GLDataType(format),
                     pixel_source);
}

void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
                                               const gfx::Rect& image_rect,
                                               const gfx::Rect& source_rect,
                                               gfx::Vector2d dest_offset,
                                               ResourceFormat format) {
  TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage");

  // Early-out if this is a no-op, and assert that |image| be valid if this is
  // not a no-op.
  if (source_rect.IsEmpty())
    return;
  DCHECK(image);
  // Compressed textures have no implementation of mapTexSubImage.
  DCHECK_NE(ETC1, format);

  // Offset from image-rect to source-rect.
  gfx::Vector2d offset(source_rect.origin() - image_rect.origin());

  unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
  // Use 4-byte row alignment (OpenGL default) for upload performance.
  // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
  unsigned upload_image_stride =
      RoundUp(bytes_per_pixel * source_rect.width(), 4u);

  // Upload tile data via a mapped transfer buffer
  uint8* pixel_dest =
      static_cast<uint8*>(gl_->MapTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
                                                        0,
                                                        dest_offset.x(),
                                                        dest_offset.y(),
                                                        source_rect.width(),
                                                        source_rect.height(),
                                                        GLDataFormat(format),
                                                        GLDataType(format),
                                                        GL_WRITE_ONLY));

  if (!pixel_dest) {
    UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format);
    return;
  }

  if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
      !offset.x()) {
    memcpy(pixel_dest,
           &image[image_rect.width() * bytes_per_pixel * offset.y()],
           source_rect.height() * image_rect.width() * bytes_per_pixel);
  } else {
    // Strides not equal, so do a row-by-row memcpy from the
    // paint results into the pixel_dest.
    for (int row = 0; row < source_rect.height(); ++row) {
      memcpy(&pixel_dest[upload_image_stride * row],
             &image[bytes_per_pixel *
                    (offset.x() + (offset.y() + row) * image_rect.width())],
             source_rect.width() * bytes_per_pixel);
    }
  }

  gl_->UnmapTexSubImage2DCHROMIUM(pixel_dest);
}

void TextureUploader::UploadWithTexImageETC1(const uint8* image,
                                             const gfx::Size& size) {
  TRACE_EVENT0("cc", "TextureUploader::UploadWithTexImageETC1");
  DCHECK_EQ(0, size.width() % 4);
  DCHECK_EQ(0, size.height() % 4);

  gl_->CompressedTexImage2D(GL_TEXTURE_2D,
                            0,
                            GLInternalFormat(ETC1),
                            size.width(),
                            size.height(),
                            0,
                            Resource::MemorySizeBytes(size, ETC1),
                            image);
}

void TextureUploader::ProcessQueries() {
  while (!pending_queries_.empty()) {
    if (pending_queries_.front()->IsPending())
      break;

    unsigned us_elapsed = pending_queries_.front()->Value();
    UMA_HISTOGRAM_CUSTOM_COUNTS(
        "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50);

    // Clamp the queries to saner values in case the queries fail.
    us_elapsed = std::max(1u, us_elapsed);
    us_elapsed = std::min(15000u, us_elapsed);

    if (!pending_queries_.front()->is_non_blocking())
      num_blocking_texture_uploads_--;

    // Remove the min and max value from our history and insert the new one.
    double textures_per_second = 1.0 / (us_elapsed * 1e-6);
    if (textures_per_second_history_.size() >= kUploadHistorySizeMax) {
      textures_per_second_history_.erase(textures_per_second_history_.begin());
      textures_per_second_history_.erase(--textures_per_second_history_.end());
    }
    textures_per_second_history_.insert(textures_per_second);

    available_queries_.push_back(pending_queries_.take_front());
  }
}

}  // namespace cc
