// Copyright 2012 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/layers/heads_up_display_layer_impl.h"

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

#include <algorithm>
#include <vector>

#include "base/memory/shared_memory_mapping.h"
#include "base/numerics/safe_conversions.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/debug/debug_colors.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_shader.h"
#include "cc/paint/record_paint_canvas.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/raster/scoped_gpu_raster.h"
#include "cc/resources/memory_history.h"
#include "cc/trees/frame_rate_counter.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/platform_color.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/config/gpu_feature_info.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/trace_util.h"

namespace cc {

namespace {

void DrawArc(PaintCanvas* canvas,
             const SkRect& oval,
             SkScalar start_angle,
             SkScalar sweep_angle,
             const PaintFlags& flags) {
  DCHECK_GT(sweep_angle, 0.f);
  DCHECK_LT(sweep_angle, 360.f);
  SkPath path;
  path.moveTo(oval.centerX(), oval.centerY());
  path.arcTo(oval, start_angle, sweep_angle, false /* forceMoveTo */);
  path.close();
  canvas->drawPath(path, flags);
}

class DummyImageProvider : public ImageProvider {
 public:
  DummyImageProvider() = default;
  ~DummyImageProvider() override = default;
  ImageProvider::ScopedResult GetRasterContent(
      const DrawImage& draw_image) override {
    NOTREACHED();
    return ScopedResult();
  }
};

}  // namespace

HeadsUpDisplayLayerImpl::Graph::Graph(double indicator_value,
                                      double start_upper_bound)
    : value(0.0),
      min(0.0),
      max(0.0),
      current_upper_bound(start_upper_bound),
      default_upper_bound(start_upper_bound),
      indicator(indicator_value) {}

double HeadsUpDisplayLayerImpl::Graph::UpdateUpperBound() {
  double target_upper_bound = std::max(max, default_upper_bound);
  current_upper_bound += (target_upper_bound - current_upper_bound) * 0.5;
  return current_upper_bound;
}

HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl,
                                                 int id)
    : LayerImpl(tree_impl, id),
      internal_contents_scale_(1.f),
      fps_graph_(60.0, 80.0),
      paint_time_graph_(16.0, 48.0) {}

HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() {
  ReleaseResources();
}

std::unique_ptr<LayerImpl> HeadsUpDisplayLayerImpl::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return HeadsUpDisplayLayerImpl::Create(tree_impl, id());
}

class HudGpuBacking : public ResourcePool::GpuBacking {
 public:
  ~HudGpuBacking() override {
    if (mailbox.IsZero())
      return;
    if (returned_sync_token.HasData())
      shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
    else if (mailbox_sync_token.HasData())
      shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
  }

  void OnMemoryDump(
      base::trace_event::ProcessMemoryDump* pmd,
      const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
      uint64_t tracing_process_id,
      int importance) const override {
    if (mailbox.IsZero())
      return;

    auto tracing_guid = gpu::GetSharedImageGUIDForTracing(mailbox);
    pmd->CreateSharedGlobalAllocatorDump(tracing_guid);
    pmd->AddOwnershipEdge(buffer_dump_guid, tracing_guid, importance);
  }

  gpu::SharedImageInterface* shared_image_interface = nullptr;
};

class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
 public:
  ~HudSoftwareBacking() override {
    layer_tree_frame_sink->DidDeleteSharedBitmap(shared_bitmap_id);
  }

  void OnMemoryDump(
      base::trace_event::ProcessMemoryDump* pmd,
      const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
      uint64_t tracing_process_id,
      int importance) const override {
    pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid,
                                         shared_mapping.guid(), importance);
  }

  LayerTreeFrameSink* layer_tree_frame_sink;
  base::WritableSharedMemoryMapping shared_mapping;
};

bool HeadsUpDisplayLayerImpl::WillDraw(
    DrawMode draw_mode,
    viz::ClientResourceProvider* resource_provider) {
  if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE &&
      !LayerImpl::WillDraw(draw_mode, resource_provider)) {
    return false;
  }

  int max_texture_size = layer_tree_impl()->max_texture_size();
  internal_contents_scale_ = GetIdealContentsScale();
  internal_content_bounds_ =
      gfx::ScaleToCeiledSize(bounds(), internal_contents_scale_);
  internal_content_bounds_.SetToMin(
      gfx::Size(max_texture_size, max_texture_size));

  return true;
}

void HeadsUpDisplayLayerImpl::AppendQuads(viz::RenderPass* render_pass,
                                          AppendQuadsData* append_quads_data) {
  viz::SharedQuadState* shared_quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  PopulateScaledSharedQuadState(shared_quad_state, internal_contents_scale_,
                                internal_contents_scale_, contents_opaque());

  // Appends a dummy quad here, which will be updated later once the resource
  // is ready in UpdateHudTexture(). We don't add a TextureDrawQuad directly
  // because we don't have a ResourceId for it yet, and ValidateQuadResources()
  // would fail. UpdateHudTexture() happens after all quads are appended for all
  // layers.
  gfx::Rect quad_rect(internal_content_bounds_);
  auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  quad->SetNew(shared_quad_state, quad_rect, quad_rect, SK_ColorTRANSPARENT,
               false);
  ValidateQuadResources(quad);
  current_quad_ = quad;
}

void HeadsUpDisplayLayerImpl::UpdateHudTexture(
    DrawMode draw_mode,
    LayerTreeFrameSink* layer_tree_frame_sink,
    viz::ClientResourceProvider* resource_provider,
    bool gpu_raster,
    const viz::RenderPassList& list) {
  if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
    return;

  // Update state that will be drawn.
  UpdateHudContents();

  // TODO(penghuang): Do not use worker_context_provider() when context_provider
  // is changed to RasterContextProvider.
  // https://crbug.com/c/1286950
  auto* raster_context_provider =
      gpu_raster ? layer_tree_frame_sink->worker_context_provider() : nullptr;
  base::Optional<viz::RasterContextProvider::ScopedRasterContextLock> lock;
  bool use_oopr = false;
  if (raster_context_provider) {
    lock.emplace(raster_context_provider);
    use_oopr = raster_context_provider->GetGpuFeatureInfo()
                   .status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
               gpu::kGpuFeatureStatusEnabled;
    if (!use_oopr) {
      raster_context_provider = nullptr;
      lock.reset();
    }
  }

  auto* context_provider = layer_tree_frame_sink->context_provider();
  if (!pool_) {
    scoped_refptr<base::SingleThreadTaskRunner> task_runner =
        layer_tree_impl()->task_runner_provider()->HasImplThread()
            ? layer_tree_impl()->task_runner_provider()->ImplThreadTaskRunner()
            : layer_tree_impl()->task_runner_provider()->MainThreadTaskRunner();
    pool_ = std::make_unique<ResourcePool>(
        resource_provider, context_provider, std::move(task_runner),
        ResourcePool::kDefaultExpirationDelay,
        layer_tree_impl()->settings().disallow_non_exact_resource_reuse);
  }

  // Return ownership of the previous frame's resource to the pool, so we
  // can reuse it once it is not busy in the display compositor. This is safe to
  // do here because the previous frame has been shipped to the display
  // compositor by the time we UpdateHudTexture for the current frame.
  if (in_flight_resource_)
    pool_->ReleaseResource(std::move(in_flight_resource_));

  // Allocate a backing for the resource if needed, either for gpu or software
  // compositing.
  ResourcePool::InUsePoolResource pool_resource;
  if (draw_mode == DRAW_MODE_HARDWARE) {
    DCHECK(raster_context_provider || context_provider);
    const auto& caps = raster_context_provider
                           ? raster_context_provider->ContextCapabilities()
                           : context_provider->ContextCapabilities();
    viz::ResourceFormat format =
        gpu_raster ? viz::PlatformColor::BestSupportedRenderBufferFormat(caps)
                   : viz::PlatformColor::BestSupportedTextureFormat(caps);
    pool_resource = pool_->AcquireResource(internal_content_bounds_, format,
                                           gfx::ColorSpace());

    if (!pool_resource.gpu_backing()) {
      auto backing = std::make_unique<HudGpuBacking>();
      auto* sii = raster_context_provider
                      ? raster_context_provider->SharedImageInterface()
                      : context_provider->SharedImageInterface();
      backing->shared_image_interface = sii;
      backing->InitOverlayCandidateAndTextureTarget(
          pool_resource.format(), caps,
          layer_tree_impl()
              ->settings()
              .resource_settings.use_gpu_memory_buffer_resources);

      uint32_t flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
      if (use_oopr) {
        flags |= gpu::SHARED_IMAGE_USAGE_RASTER |
                 gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
      } else if (gpu_raster) {
        flags |= gpu::SHARED_IMAGE_USAGE_GLES2 |
                 gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
      }
      if (backing->overlay_candidate)
        flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
      backing->mailbox =
          sii->CreateSharedImage(pool_resource.format(), pool_resource.size(),
                                 pool_resource.color_space(), flags);
      if (raster_context_provider) {
        auto* ri = raster_context_provider->RasterInterface();
        ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
      } else {
        auto* gl = context_provider->ContextGL();
        gl->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());
      }
      pool_resource.set_gpu_backing(std::move(backing));
    } else if (pool_resource.gpu_backing()->returned_sync_token.HasData()) {
      if (raster_context_provider) {
        auto* ri = raster_context_provider->RasterInterface();
        ri->WaitSyncTokenCHROMIUM(
            pool_resource.gpu_backing()->returned_sync_token.GetConstData());
      } else {
        auto* gl = context_provider->ContextGL();
        gl->WaitSyncTokenCHROMIUM(
            pool_resource.gpu_backing()->returned_sync_token.GetConstData());
      }
      pool_resource.gpu_backing()->returned_sync_token = gpu::SyncToken();
    }
  } else {
    DCHECK_EQ(draw_mode, DRAW_MODE_SOFTWARE);

    pool_resource = pool_->AcquireResource(internal_content_bounds_,
                                           viz::RGBA_8888, gfx::ColorSpace());

    if (!pool_resource.software_backing()) {
      auto backing = std::make_unique<HudSoftwareBacking>();
      backing->layer_tree_frame_sink = layer_tree_frame_sink;
      backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
      base::MappedReadOnlyRegion shm =
          viz::bitmap_allocation::AllocateSharedBitmap(pool_resource.size(),
                                                       pool_resource.format());
      backing->shared_mapping = std::move(shm.mapping);

      layer_tree_frame_sink->DidAllocateSharedBitmap(std::move(shm.region),
                                                     backing->shared_bitmap_id);

      pool_resource.set_software_backing(std::move(backing));
    }
  }

  if (gpu_raster) {
    // If using |gpu_raster| we DrawHudContents() directly to a gpu texture,
    // which is wrapped in an SkSurface.
    DCHECK_EQ(draw_mode, DRAW_MODE_HARDWARE);
    DCHECK(pool_resource.gpu_backing());
    auto* backing = static_cast<HudGpuBacking*>(pool_resource.gpu_backing());

    if (use_oopr) {
      const auto& size = pool_resource.size();
      auto display_item_list = base::MakeRefCounted<DisplayItemList>(
          DisplayItemList::kTopLevelDisplayItemList);
      RecordPaintCanvas canvas(display_item_list.get(),
                               SkRect::MakeIWH(size.width(), size.height()));
      display_item_list->StartPaint();
      DrawHudContents(&canvas);
      display_item_list->EndPaintOfUnpaired(gfx::Rect(size));
      display_item_list->Finalize();

      auto* ri = raster_context_provider->RasterInterface();
      constexpr GLuint background_color = SkColorSetARGB(0, 0, 0, 0);
      constexpr GLuint msaa_sample_count = -1;
      constexpr bool can_use_lcd_text = true;
      ri->BeginRasterCHROMIUM(background_color, msaa_sample_count,
                              can_use_lcd_text, gfx::ColorSpace::CreateSRGB(),
                              backing->mailbox.name);
      gfx::Vector2dF post_translate(0.f, 0.f);
      DummyImageProvider image_provider;
      size_t max_op_size_limit =
          gpu::raster::RasterInterface::kDefaultMaxOpSizeHint;
      ri->RasterCHROMIUM(display_item_list.get(), &image_provider, size,
                         gfx::Rect(size), gfx::Rect(size), post_translate,
                         1.f /* post_scale */, false /* requires_clear */,
                         &max_op_size_limit);
      ri->EndRasterCHROMIUM();
      backing->mailbox_sync_token =
          viz::ClientResourceProvider::GenerateSyncTokenHelper(ri);
    } else {
      auto* gl = context_provider->ContextGL();
      GLuint mailbox_texture_id =
          gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);

      {
        ScopedGpuRaster gpu_raster(context_provider);
        viz::ClientResourceProvider::ScopedSkSurface scoped_surface(
            context_provider->GrContext(),
            pool_resource.color_space().ToSkColorSpace(), mailbox_texture_id,
            backing->texture_target, pool_resource.size(),
            pool_resource.format(), false /* can_use_lcd_text */,
            0 /* msaa_sample_count */);
        SkSurface* surface = scoped_surface.surface();
        if (!surface) {
          pool_->ReleaseResource(std::move(pool_resource));
          return;
        }
        SkiaPaintCanvas canvas(surface->getCanvas());
        DrawHudContents(&canvas);
      }

      gl->DeleteTextures(1, &mailbox_texture_id);
      backing->mailbox_sync_token =
          viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
    }
  } else if (draw_mode == DRAW_MODE_HARDWARE) {
    // If not using |gpu_raster| but using gpu compositing, we DrawHudContents()
    // into a software bitmap and upload it to a texture for compositing.
    DCHECK(pool_resource.gpu_backing());
    auto* backing = static_cast<HudGpuBacking*>(pool_resource.gpu_backing());
    viz::ContextProvider* context_provider =
        layer_tree_impl()->context_provider();
    gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();

    if (!staging_surface_ ||
        gfx::SkISizeToSize(staging_surface_->getCanvas()->getBaseLayerSize()) !=
            pool_resource.size()) {
      staging_surface_ = SkSurface::MakeRasterN32Premul(
          pool_resource.size().width(), pool_resource.size().height());
    }

    SkiaPaintCanvas canvas(staging_surface_->getCanvas());
    DrawHudContents(&canvas);

    TRACE_EVENT0("cc", "UploadHudTexture");
    SkPixmap pixmap;
    staging_surface_->peekPixels(&pixmap);
    GLuint mailbox_texture_id =
        gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
    gl->BindTexture(backing->texture_target, mailbox_texture_id);
    DCHECK(GLSupportsFormat(pool_resource.format()));
    // We should use gl compatible format for skia SW rasterization.
    constexpr GLenum format = SK_B32_SHIFT ? GL_RGBA : GL_BGRA_EXT;
    constexpr GLenum type = GL_UNSIGNED_BYTE;
    gl->TexSubImage2D(
        backing->texture_target, 0, 0, 0, pool_resource.size().width(),
        pool_resource.size().height(), format, type, pixmap.addr());
    gl->DeleteTextures(1, &mailbox_texture_id);
    backing->mailbox_sync_token =
        viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
  } else {
    // If not using gpu compositing, we DrawHudContents() directly into a shared
    // memory bitmap, wrapped in an SkSurface, that can be shared to the display
    // compositor.
    DCHECK_EQ(draw_mode, DRAW_MODE_SOFTWARE);
    DCHECK(pool_resource.software_backing());

    SkImageInfo info = SkImageInfo::MakeN32Premul(
        pool_resource.size().width(), pool_resource.size().height());
    auto* backing =
        static_cast<HudSoftwareBacking*>(pool_resource.software_backing());
    sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
        info, backing->shared_mapping.memory(), info.minRowBytes());

    SkiaPaintCanvas canvas(surface->getCanvas());
    DrawHudContents(&canvas);
  }

  // Exports the backing to the ResourceProvider, giving it a ResourceId that
  // can be used in a DrawQuad.
  bool exported = pool_->PrepareForExport(pool_resource);
  DCHECK(exported);
  viz::ResourceId resource_id = pool_resource.resource_id_for_export();

  // Save the resource to prevent reuse until it is exported to the display
  // compositor. Next time we come here, we can release it back to the pool as
  // it will be exported by then.
  in_flight_resource_ = std::move(pool_resource);

  // This iterates over the RenderPass list of quads to find the HUD quad, which
  // will always be in the root RenderPass.
  auto& render_pass = list.back();
  for (auto it = render_pass->quad_list.begin();
       it != render_pass->quad_list.end(); ++it) {
    if (*it == current_quad_) {
      const viz::SharedQuadState* sqs = current_quad_->shared_quad_state;
      gfx::Rect quad_rect = current_quad_->rect;
      gfx::Rect visible_rect = current_quad_->visible_rect;
      current_quad_ = nullptr;

      auto* quad =
          render_pass->quad_list.ReplaceExistingElement<viz::TextureDrawQuad>(
              it);

      const float vertex_opacity[] = {1.f, 1.f, 1.f, 1.f};
      quad->SetNew(sqs, quad_rect, visible_rect, /*needs_blending=*/true,
                   resource_id, /*premultiplied_alpha=*/true,
                   /*uv_top_left=*/gfx::PointF(),
                   /*uv_bottom_right=*/gfx::PointF(1.f, 1.f),
                   /*background_color=*/SK_ColorTRANSPARENT, vertex_opacity,
                   /*flipped=*/false,
                   /*nearest_neighbor=*/false, /*secure_output_only=*/false,
                   gfx::ProtectedVideoType::kClear);
      ValidateQuadResources(quad);
      break;
    }
  }
  // If this fails, we didn't find |current_quad_| in the root RenderPass, so we
  // didn't append it for the frame (why are we here then?), or it landed in
  // some other RenderPass, both of which are unexpected.
  DCHECK(!current_quad_);
}

void HeadsUpDisplayLayerImpl::ReleaseResources() {
  if (in_flight_resource_)
    pool_->ReleaseResource(std::move(in_flight_resource_));
  pool_.reset();
}

gfx::Rect HeadsUpDisplayLayerImpl::GetEnclosingRectInTargetSpace() const {
  DCHECK_GT(internal_contents_scale_, 0.f);
  return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_);
}

void HeadsUpDisplayLayerImpl::SetHUDTypeface(sk_sp<SkTypeface> typeface) {
  if (typeface_ == typeface)
    return;

  DCHECK(typeface_.get() == nullptr);
  typeface_ = std::move(typeface);
  NoteLayerPropertyChanged();
}

const std::vector<gfx::Rect>& HeadsUpDisplayLayerImpl::LayoutShiftRects()
    const {
  return layout_shift_rects_;
}

void HeadsUpDisplayLayerImpl::SetLayoutShiftRects(
    const std::vector<gfx::Rect>& rects) {
  layout_shift_rects_ = rects;
}

void HeadsUpDisplayLayerImpl::PushPropertiesTo(LayerImpl* layer) {
  LayerImpl::PushPropertiesTo(layer);

  HeadsUpDisplayLayerImpl* layer_impl =
      static_cast<HeadsUpDisplayLayerImpl*>(layer);

  layer_impl->SetHUDTypeface(typeface_);
  layer_impl->SetLayoutShiftRects(layout_shift_rects_);
  layout_shift_rects_.clear();
}

void HeadsUpDisplayLayerImpl::UpdateHudContents() {
  const LayerTreeDebugState& debug_state = layer_tree_impl()->debug_state();

  // Don't update numbers every frame so text is readable.
  base::TimeTicks now = layer_tree_impl()->CurrentBeginFrameArgs().frame_time;
  if (base::TimeDelta(now - time_of_last_graph_update_).InSecondsF() > 0.25f) {
    time_of_last_graph_update_ = now;

    if (debug_state.show_fps_counter) {
      FrameRateCounter* fps_counter = layer_tree_impl()->frame_rate_counter();
      fps_graph_.value = fps_counter->GetAverageFPS();
      fps_counter->GetMinAndMaxFPS(&fps_graph_.min, &fps_graph_.max);
    }

    if (debug_state.ShowMemoryStats()) {
      MemoryHistory* memory_history = layer_tree_impl()->memory_history();
      if (memory_history->End())
        memory_entry_ = **memory_history->End();
      else
        memory_entry_ = MemoryHistory::Entry();
    }
  }

  fps_graph_.UpdateUpperBound();
  paint_time_graph_.UpdateUpperBound();
}

void HeadsUpDisplayLayerImpl::DrawHudContents(PaintCanvas* canvas) {
  const LayerTreeDebugState& debug_state = layer_tree_impl()->debug_state();

  TRACE_EVENT0("cc", "DrawHudContents");
  canvas->clear(SkColorSetARGB(0, 0, 0, 0));
  canvas->save();
  canvas->scale(internal_contents_scale_, internal_contents_scale_);

  if (debug_state.ShowHudRects()) {
    DrawDebugRects(canvas, layer_tree_impl()->debug_rect_history());
    if (IsAnimatingHUDContents()) {
      layer_tree_impl()->SetNeedsRedraw();
    }
  }

  if (!debug_state.show_fps_counter) {
    canvas->restore();
    return;
  }

  SkRect area =
      DrawFPSDisplay(canvas, layer_tree_impl()->frame_rate_counter(), 0, 0);
  area = DrawGpuRasterizationStatus(canvas, 0, area.bottom(),
                                    SkMaxScalar(area.width(), 150));

  if (debug_state.ShowMemoryStats() && memory_entry_.total_bytes_used)
    DrawMemoryDisplay(canvas, 0, area.bottom(), SkMaxScalar(area.width(), 150));

  canvas->restore();
}

void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
                                       const PaintFlags& flags,
                                       const std::string& text,
                                       TextAlign align,
                                       int size,
                                       int x,
                                       int y) const {
  DCHECK(typeface_.get());
  SkFont font(typeface_, size);
  font.setEdging(SkFont::Edging::kAntiAlias);

  if (align == TextAlign::kCenter) {
    auto width =
        font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
    x -= width * 0.5f;
  } else if (align == TextAlign::kRight) {
    auto width =
        font.measureText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
    x -= width;
  }

  canvas->drawTextBlob(
      SkTextBlob::MakeFromText(text.c_str(), text.length(), font), x, y, flags);
}

void HeadsUpDisplayLayerImpl::DrawText(PaintCanvas* canvas,
                                       const PaintFlags& flags,
                                       const std::string& text,
                                       TextAlign align,
                                       int size,
                                       const SkPoint& pos) const {
  DrawText(canvas, flags, text, align, size, pos.x(), pos.y());
}

void HeadsUpDisplayLayerImpl::DrawGraphBackground(PaintCanvas* canvas,
                                                  PaintFlags* flags,
                                                  const SkRect& bounds) const {
  flags->setColor(DebugColors::HUDBackgroundColor());
  canvas->drawRect(bounds, *flags);
}

void HeadsUpDisplayLayerImpl::DrawGraphLines(PaintCanvas* canvas,
                                             PaintFlags* flags,
                                             const SkRect& bounds,
                                             const Graph& graph) const {
  // Draw top and bottom line.
  flags->setColor(DebugColors::HUDSeparatorLineColor());
  canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(),
                   bounds.top() - 1, *flags);
  canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(),
                   bounds.bottom(), *flags);

  // Draw indicator line (additive blend mode to increase contrast when drawn on
  // top of graph).
  flags->setColor(DebugColors::HUDIndicatorLineColor());
  flags->setBlendMode(SkBlendMode::kPlus);
  const double indicator_top =
      bounds.height() * (1.0 - graph.indicator / graph.current_upper_bound) -
      1.0;
  canvas->drawLine(bounds.left(), bounds.top() + indicator_top, bounds.right(),
                   bounds.top() + indicator_top, *flags);
  flags->setBlendMode(SkBlendMode::kSrcOver);
}

SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
    PaintCanvas* canvas,
    const FrameRateCounter* fps_counter,
    int right,
    int top) const {
  const int kPadding = 4;
  const int kGap = 6;

  const int kTitleFontHeight = 13;
  const int kFontHeight = 12;

  const int kGraphWidth =
      base::saturated_cast<int>(fps_counter->time_stamp_history_size()) - 2;
  const int kGraphHeight = 40;

  const int kHistogramWidth = 37;

  int width = kGraphWidth + kHistogramWidth + 4 * kPadding;
  int height = kTitleFontHeight + kFontHeight + kGraphHeight + 6 * kPadding + 2;
  int left = 0;
  SkRect area = SkRect::MakeXYWH(left, top, width, height);

  PaintFlags flags;
  DrawGraphBackground(canvas, &flags, area);

  SkRect title_bounds = SkRect::MakeXYWH(
      left + kPadding, top + kPadding, kGraphWidth + kHistogramWidth + kGap + 2,
      kTitleFontHeight);
  SkRect text_bounds =
      SkRect::MakeXYWH(left + kPadding, title_bounds.bottom() + 2 * kPadding,
                       kGraphWidth + kHistogramWidth + kGap + 2, kFontHeight);
  SkRect graph_bounds =
      SkRect::MakeXYWH(left + kPadding, text_bounds.bottom() + 2 * kPadding,
                       kGraphWidth, kGraphHeight);
  SkRect histogram_bounds =
      SkRect::MakeXYWH(graph_bounds.right() + kGap, graph_bounds.top(),
                       kHistogramWidth, kGraphHeight);

  const std::string title("Frame Rate");
  const std::string value_text =
      base::StringPrintf("%5.1f fps", fps_graph_.value);
  const std::string min_max_text =
      base::StringPrintf("%.0f-%.0f", fps_graph_.min, fps_graph_.max);

  VLOG(1) << value_text;

  flags.setColor(DebugColors::HUDTitleColor());
  DrawText(canvas, flags, title, TextAlign::kLeft, kTitleFontHeight,
           title_bounds.left(), title_bounds.bottom());

  flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
  DrawText(canvas, flags, value_text, TextAlign::kLeft, kFontHeight,
           text_bounds.left(), text_bounds.bottom());
  DrawText(canvas, flags, min_max_text, TextAlign::kRight, kFontHeight,
           text_bounds.right(), text_bounds.bottom());

  DrawGraphLines(canvas, &flags, graph_bounds, fps_graph_);

  // Collect graph and histogram data.
  SkPath path;

  const int kHistogramSize = 20;
  double histogram[kHistogramSize] = {1.0};
  double max_bucket_value = 1.0;

  for (FrameRateCounter::RingBufferType::Iterator it = --fps_counter->end(); it;
       --it) {
    base::TimeDelta delta = fps_counter->RecentFrameInterval(it.index() + 1);

    // Skip this particular instantaneous frame rate if it is not likely to have
    // been valid.
    if (!fps_counter->IsBadFrameInterval(delta)) {
      double fps = 1.0 / delta.InSecondsF();

      // Clamp the FPS to the range we want to plot visually.
      double p = fps / fps_graph_.current_upper_bound;
      if (p > 1.0)
        p = 1.0;

      // Plot this data point.
      SkPoint cur =
          SkPoint::Make(graph_bounds.left() + it.index(),
                        graph_bounds.bottom() - p * graph_bounds.height());
      if (path.isEmpty())
        path.moveTo(cur);
      else
        path.lineTo(cur);

      // Use the fps value to find the right bucket in the histogram.
      int bucket_index = floor(p * (kHistogramSize - 1));

      // Add the delta time to take the time spent at that fps rate into
      // account.
      histogram[bucket_index] += delta.InSecondsF();
      max_bucket_value = std::max(histogram[bucket_index], max_bucket_value);
    }
  }

  // Draw FPS histogram.
  flags.setColor(DebugColors::HUDSeparatorLineColor());
  canvas->drawLine(histogram_bounds.left() - 1, histogram_bounds.top() - 1,
                   histogram_bounds.left() - 1, histogram_bounds.bottom() + 1,
                   flags);
  canvas->drawLine(histogram_bounds.right() + 1, histogram_bounds.top() - 1,
                   histogram_bounds.right() + 1, histogram_bounds.bottom() + 1,
                   flags);

  flags.setColor(DebugColors::FPSDisplayTextAndGraphColor());
  const double bar_height = histogram_bounds.height() / kHistogramSize;

  for (int i = kHistogramSize - 1; i >= 0; --i) {
    if (histogram[i] > 0) {
      double bar_width =
          histogram[i] / max_bucket_value * histogram_bounds.width();
      canvas->drawRect(
          SkRect::MakeXYWH(histogram_bounds.left(),
                           histogram_bounds.bottom() - (i + 1) * bar_height,
                           bar_width, 1),
          flags);
    }
  }

  // Draw FPS graph.
  flags.setAntiAlias(true);
  flags.setStyle(PaintFlags::kStroke_Style);
  flags.setStrokeWidth(1);
  canvas->drawPath(path, flags);

  return area;
}

SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(PaintCanvas* canvas,
                                                  int right,
                                                  int top,
                                                  int width) const {
  const int kPadding = 4;
  const int kTitleFontHeight = 13;
  const int kFontHeight = 12;

  const int height = kTitleFontHeight + 2 * kFontHeight + 5 * kPadding;
  const int left = 0;
  const SkRect area = SkRect::MakeXYWH(left, top, width, height);

  const double kMegabyte = 1024.0 * 1024.0;

  PaintFlags flags;
  DrawGraphBackground(canvas, &flags, area);

  SkPoint title_pos =
      SkPoint::Make(left + kPadding, top + kFontHeight + kPadding);
  SkPoint stat1_pos = SkPoint::Make(left + width - kPadding - 1,
                                    top + kPadding + 2 * kFontHeight);
  SkPoint stat2_pos = SkPoint::Make(left + width - kPadding - 1,
                                    top + 2 * kPadding + 3 * kFontHeight);

  flags.setColor(DebugColors::HUDTitleColor());
  DrawText(canvas, flags, "GPU Memory", TextAlign::kLeft, kTitleFontHeight,
           title_pos);

  flags.setColor(DebugColors::MemoryDisplayTextColor());
  std::string text = base::StringPrintf(
      "%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte);
  DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat1_pos);

  if (!memory_entry_.had_enough_memory)
    flags.setColor(SK_ColorRED);
  text = base::StringPrintf("%6.1f MB max ",
                            memory_entry_.total_budget_in_bytes / kMegabyte);

  DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat2_pos);

  // Draw memory graph.
  int length = 2 * kFontHeight + kPadding + 12;
  SkRect oval =
      SkRect::MakeXYWH(left + kPadding * 6,
                       top + kTitleFontHeight + kPadding * 3, length, length);
  flags.setAntiAlias(true);
  flags.setStyle(PaintFlags::kFill_Style);

  flags.setColor(SkColorSetARGB(64, 255, 255, 0));
  DrawArc(canvas, oval, 180, 180, flags);

  int radius = length / 2;
  int cx = oval.left() + radius;
  int cy = oval.top() + radius;
  double angle = ((double)memory_entry_.total_bytes_used /
                  memory_entry_.total_budget_in_bytes) *
                 180;

  SkColor colors[] = {SK_ColorRED, SK_ColorGREEN, SK_ColorGREEN,
                      SkColorSetARGB(255, 255, 140, 0), SK_ColorRED};
  const SkScalar pos[] = {SkFloatToScalar(0.2f), SkFloatToScalar(0.4f),
                          SkFloatToScalar(0.6f), SkFloatToScalar(0.8f),
                          SkFloatToScalar(1.0f)};
  flags.setShader(PaintShader::MakeSweepGradient(cx, cy, colors, pos, 5,
                                                 SkTileMode::kClamp, 0, 360));
  flags.setAntiAlias(true);

  // Draw current status.
  flags.setStyle(PaintFlags::kStroke_Style);
  flags.setAlpha(32);
  flags.setStrokeWidth(4);
  DrawArc(canvas, oval, 180, angle, flags);

  flags.setStyle(PaintFlags::kFill_Style);
  flags.setColor(SkColorSetARGB(255, 0, 255, 0));
  DrawArc(canvas, oval, 180, angle, flags);
  flags.setShader(nullptr);

  return area;
}

SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
                                                           int right,
                                                           int top,
                                                           int width) const {
  std::string status;
  SkColor color = SK_ColorRED;
  switch (layer_tree_impl()->GetGpuRasterizationStatus()) {
    case GpuRasterizationStatus::ON:
      status = "on";
      color = SK_ColorGREEN;
      break;
    case GpuRasterizationStatus::ON_FORCED:
      status = "on (forced)";
      color = SK_ColorGREEN;
      break;
    case GpuRasterizationStatus::OFF_DEVICE:
      status = "off (device)";
      color = SK_ColorRED;
      break;
    case GpuRasterizationStatus::OFF_VIEWPORT:
      status = "off (viewport)";
      color = SK_ColorYELLOW;
      break;
    case GpuRasterizationStatus::MSAA_CONTENT:
      status = "MSAA (content)";
      color = SK_ColorCYAN;
      break;
  }

  if (status.empty())
    return SkRect::MakeEmpty();

  const int kPadding = 4;
  const int kTitleFontHeight = 13;
  const int kFontHeight = 12;

  const int height = kTitleFontHeight + kFontHeight + 3 * kPadding;
  const int left = 0;
  const SkRect area = SkRect::MakeXYWH(left, top, width, height);

  PaintFlags flags;
  DrawGraphBackground(canvas, &flags, area);

  SkPoint gpu_status_pos = SkPoint::Make(left + width - kPadding,
                                         top + 2 * kFontHeight + 2 * kPadding);
  flags.setColor(DebugColors::HUDTitleColor());
  DrawText(canvas, flags, "GPU Raster", TextAlign::kLeft, kTitleFontHeight,
           left + kPadding, top + kFontHeight + kPadding);
  flags.setColor(color);
  DrawText(canvas, flags, status, TextAlign::kRight, kFontHeight,
           gpu_status_pos);

  return area;
}

void HeadsUpDisplayLayerImpl::DrawDebugRect(
    PaintCanvas* canvas,
    PaintFlags* flags,
    const DebugRect& rect,
    SkColor stroke_color,
    SkColor fill_color,
    float stroke_width,
    const std::string& label_text) const {
  DCHECK(typeface_.get());
  gfx::Rect debug_layer_rect =
      gfx::ScaleToEnclosingRect(rect.rect, 1.0 / internal_contents_scale_,
                                1.0 / internal_contents_scale_);
  SkIRect sk_rect = RectToSkIRect(debug_layer_rect);
  flags->setColor(fill_color);
  flags->setStyle(PaintFlags::kFill_Style);
  canvas->drawIRect(sk_rect, *flags);

  flags->setColor(stroke_color);
  flags->setStyle(PaintFlags::kStroke_Style);
  flags->setStrokeWidth(SkFloatToScalar(stroke_width));
  canvas->drawIRect(sk_rect, *flags);

  if (label_text.length()) {
    const int kFontHeight = 12;
    const int kPadding = 3;

    // The debug_layer_rect may be huge, and converting to a floating point may
    // be lossy, so intersect with the HUD layer bounds first to prevent that.
    gfx::Rect clip_rect = debug_layer_rect;
    clip_rect.Intersect(gfx::Rect(internal_content_bounds_));
    SkRect sk_clip_rect = RectToSkRect(clip_rect);

    canvas->save();
    canvas->clipRect(sk_clip_rect);
    canvas->translate(sk_clip_rect.x(), sk_clip_rect.y());

    PaintFlags label_flags;
    label_flags.setColor(stroke_color);
    SkFont label_font(typeface_, kFontHeight);

    const SkScalar label_text_width = label_font.measureText(
        label_text.c_str(), label_text.length(), SkTextEncoding::kUTF8);
    canvas->drawRect(SkRect::MakeWH(label_text_width + 2 * kPadding,
                                    kFontHeight + 2 * kPadding),
                     label_flags);

    label_flags.setColor(SkColorSetARGB(255, 50, 50, 50));
    DrawText(canvas, label_flags, label_text, TextAlign::kLeft, kFontHeight,
             kPadding, kFontHeight * 0.8f + kPadding);
    canvas->restore();
  }
}

void HeadsUpDisplayLayerImpl::DrawDebugRects(
    PaintCanvas* canvas,
    DebugRectHistory* debug_rect_history) {
  PaintFlags flags;

  const std::vector<DebugRect>& debug_rects = debug_rect_history->debug_rects();
  std::vector<DebugRect> new_paint_rects;
  std::vector<DebugRect> new_layout_shift_rects;

  for (size_t i = 0; i < debug_rects.size(); ++i) {
    SkColor stroke_color = 0;
    SkColor fill_color = 0;
    float stroke_width = 0.f;
    std::string label_text;

    switch (debug_rects[i].type) {
      case LAYOUT_SHIFT_RECT_TYPE:
        new_layout_shift_rects.push_back(debug_rects[i]);
        continue;
      case PAINT_RECT_TYPE:
        new_paint_rects.push_back(debug_rects[i]);
        continue;
      case PROPERTY_CHANGED_RECT_TYPE:
        stroke_color = DebugColors::PropertyChangedRectBorderColor();
        fill_color = DebugColors::PropertyChangedRectFillColor();
        stroke_width = DebugColors::PropertyChangedRectBorderWidth();
        break;
      case SURFACE_DAMAGE_RECT_TYPE:
        stroke_color = DebugColors::SurfaceDamageRectBorderColor();
        fill_color = DebugColors::SurfaceDamageRectFillColor();
        stroke_width = DebugColors::SurfaceDamageRectBorderWidth();
        break;
      case SCREEN_SPACE_RECT_TYPE:
        stroke_color = DebugColors::ScreenSpaceLayerRectBorderColor();
        fill_color = DebugColors::ScreenSpaceLayerRectFillColor();
        stroke_width = DebugColors::ScreenSpaceLayerRectBorderWidth();
        break;
      case TOUCH_EVENT_HANDLER_RECT_TYPE:
        stroke_color = DebugColors::TouchEventHandlerRectBorderColor();
        fill_color = DebugColors::TouchEventHandlerRectFillColor();
        stroke_width = DebugColors::TouchEventHandlerRectBorderWidth();
        label_text = "touch event listener: ";
        label_text.append(TouchActionToString(debug_rects[i].touch_action));
        break;
      case WHEEL_EVENT_HANDLER_RECT_TYPE:
        stroke_color = DebugColors::WheelEventHandlerRectBorderColor();
        fill_color = DebugColors::WheelEventHandlerRectFillColor();
        stroke_width = DebugColors::WheelEventHandlerRectBorderWidth();
        label_text = "mousewheel event listener";
        break;
      case SCROLL_EVENT_HANDLER_RECT_TYPE:
        stroke_color = DebugColors::ScrollEventHandlerRectBorderColor();
        fill_color = DebugColors::ScrollEventHandlerRectFillColor();
        stroke_width = DebugColors::ScrollEventHandlerRectBorderWidth();
        label_text = "scroll event listener";
        break;
      case NON_FAST_SCROLLABLE_RECT_TYPE:
        stroke_color = DebugColors::NonFastScrollableRectBorderColor();
        fill_color = DebugColors::NonFastScrollableRectFillColor();
        stroke_width = DebugColors::NonFastScrollableRectBorderWidth();
        label_text = "repaints on scroll";
        break;
      case ANIMATION_BOUNDS_RECT_TYPE:
        stroke_color = DebugColors::LayerAnimationBoundsBorderColor();
        fill_color = DebugColors::LayerAnimationBoundsFillColor();
        stroke_width = DebugColors::LayerAnimationBoundsBorderWidth();
        label_text = "animation bounds";
        break;
    }

    DrawDebugRect(canvas, &flags, debug_rects[i], stroke_color, fill_color,
                  stroke_width, label_text);
  }

  if (new_paint_rects.size()) {
    paint_rects_.swap(new_paint_rects);
    paint_rects_fade_step_ = DebugColors::kFadeSteps;
  }
  if (paint_rects_fade_step_ > 0) {
    paint_rects_fade_step_--;
    for (size_t i = 0; i < paint_rects_.size(); ++i) {
      DrawDebugRect(canvas, &flags, paint_rects_[i],
                    DebugColors::PaintRectBorderColor(paint_rects_fade_step_),
                    DebugColors::PaintRectFillColor(paint_rects_fade_step_),
                    DebugColors::PaintRectBorderWidth(), "");
    }
  }

  if (new_layout_shift_rects.size()) {
    layout_shift_debug_rects_.swap(new_layout_shift_rects);
    layout_shift_rects_fade_step_ = DebugColors::kFadeSteps;
  }
  if (layout_shift_rects_fade_step_ > 0) {
    layout_shift_rects_fade_step_--;
    for (size_t i = 0; i < layout_shift_debug_rects_.size(); ++i) {
      DrawDebugRect(
          canvas, &flags, layout_shift_debug_rects_[i],
          DebugColors::LayoutShiftRectBorderColor(),
          DebugColors::LayoutShiftRectFillColor(layout_shift_rects_fade_step_),
          DebugColors::LayoutShiftRectBorderWidth(), "");
    }
  }
}

const char* HeadsUpDisplayLayerImpl::LayerTypeAsString() const {
  return "cc::HeadsUpDisplayLayerImpl";
}

void HeadsUpDisplayLayerImpl::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  LayerImpl::AsValueInto(dict);
  dict->SetString("layer_name", "Heads Up Display Layer");
}

}  // namespace cc
