// Copyright 2018 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 "gpu/command_buffer/common/skia_utils.h"

#include <inttypes.h>

#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkTraceMemoryDump.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gl/trace_util.h"

namespace gpu {
namespace raster {
namespace {

// Derives from SkTraceMemoryDump and implements graphics specific memory
// backing functionality.
class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump {
 public:
  // This should never outlive the provided ProcessMemoryDump, as it should
  // always be scoped to a single OnMemoryDump funciton call.
  SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
                         base::Optional<uint64_t> share_group_tracing_guid)
      : pmd_(pmd),
        share_group_tracing_guid_(share_group_tracing_guid),
        tracing_process_id_(base::trace_event::MemoryDumpManager::GetInstance()
                                ->GetTracingProcessId()) {}

  ~SkiaGpuTraceMemoryDump() override = default;

  // Overridden from SkTraceMemoryDump:
  void dumpNumericValue(const char* dump_name,
                        const char* value_name,
                        const char* units,
                        uint64_t value) override {
    auto* dump = GetOrCreateAllocatorDump(dump_name);
    dump->AddScalar(value_name, units, value);
  }
  void dumpStringValue(const char* dump_name,
                       const char* value_name,
                       const char* value) override {
    auto* dump = GetOrCreateAllocatorDump(dump_name);
    dump->AddString(value_name, "", value);
  }

  void setMemoryBacking(const char* dump_name,
                        const char* backing_type,
                        const char* backing_object_id) override {
    // For uniformity, skia provides this value as a string. Convert back to a
    // uint32_t.
    uint32_t gl_id =
        std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */);

    // Constants used by SkiaGpuTraceMemoryDump to identify different memory
    // types.
    const char* kGLTextureBackingType = "gl_texture";
    const char* kGLBufferBackingType = "gl_buffer";
    const char* kGLRenderbufferBackingType = "gl_renderbuffer";

    // Populated in if statements below.
    base::trace_event::MemoryAllocatorDumpGuid guid;

    if (share_group_tracing_guid_) {
      // If we have a |share_group_tracing_guid_|, we are in a render process
      // and need to create client texture GUIDs for aliasing with the GPU
      // process.
      if (strcmp(backing_type, kGLTextureBackingType) == 0) {
        guid = gl::GetGLTextureClientGUIDForTracing(*share_group_tracing_guid_,
                                                    gl_id);
      } else if (strcmp(backing_type, kGLBufferBackingType) == 0) {
        guid = gl::GetGLBufferGUIDForTracing(tracing_process_id_, gl_id);
      } else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) {
        guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id_, gl_id);
      }
    } else {
      // If we do not have a |share_group_tracing_guid_|, we are in the GPU
      // process, being used for OOP-R. We need to create Raster dumps for
      // aliasing with the transfer cache. Note that this is currently only
      // needed for textures (not buffers or renderbuffers).
      if (strcmp(backing_type, kGLTextureBackingType) == 0) {
        guid = gl::GetGLTextureRasterGUIDForTracing(gl_id);
      }
    }

    if (!guid.empty()) {
      pmd_->CreateSharedGlobalAllocatorDump(guid);

      auto* dump = GetOrCreateAllocatorDump(dump_name);

      const int kImportance = 2;
      pmd_->AddOwnershipEdge(dump->guid(), guid, kImportance);
    }
  }

  void setDiscardableMemoryBacking(
      const char* dump_name,
      const SkDiscardableMemory& discardable_memory_object) override {
    // We don't use this class for dumping discardable memory.
    NOTREACHED();
  }

  LevelOfDetail getRequestedDetails() const override {
    // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
    // (crbug.com/499731).
    return kObjectsBreakdowns_LevelOfDetail;
  }

  bool shouldDumpWrappedObjects() const override {
    // Chrome already dumps objects it imports into Skia. Avoid duplicate dumps
    // by asking Skia not to dump them.
    return false;
  }

 private:
  // Helper to create allocator dumps.
  base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
      const char* dump_name) {
    auto* dump = pmd_->GetAllocatorDump(dump_name);
    if (!dump)
      dump = pmd_->CreateAllocatorDump(dump_name);
    return dump;
  }

  base::trace_event::ProcessMemoryDump* pmd_;
  base::Optional<uint64_t> share_group_tracing_guid_;
  uint64_t tracing_process_id_;

  DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump);
};

}  // namespace

void DumpGrMemoryStatistics(const GrContext* context,
                            base::trace_event::ProcessMemoryDump* pmd,
                            base::Optional<uint64_t> tracing_guid) {
  SkiaGpuTraceMemoryDump trace_memory_dump(pmd, tracing_guid);
  context->dumpMemoryStatistics(&trace_memory_dump);
}

void DumpBackgroundGrMemoryStatistics(
    const GrContext* context,
    base::trace_event::ProcessMemoryDump* pmd) {
  using base::trace_event::MemoryAllocatorDump;

  size_t skia_gr_cache_size;
  context->getResourceCacheUsage(nullptr /* resourceCount */,
                                 &skia_gr_cache_size);
  std::string dump_name =
      base::StringPrintf("skia/gpu_resources/context_0x%" PRIXPTR,
                         reinterpret_cast<uintptr_t>(context));
  MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
  dump->AddScalar(MemoryAllocatorDump::kNameSize,
                  MemoryAllocatorDump::kUnitsBytes, skia_gr_cache_size);
}

}  // namespace raster
}  // namespace gpu
