// Copyright 2015 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 "ui/gl/angle_platform_impl.h"

#include "base/base64.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/memory/protected_memory.h"
#include "base/memory/protected_memory_cfi.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
#include "base/trace_event/trace_event.h"
#include "third_party/angle/include/platform/Platform.h"
#include "ui/gl/gl_bindings.h"

namespace angle {

namespace {

// Place the function pointers for ANGLEGetDisplayPlatform and
// ANGLEResetDisplayPlatform in read-only memory after being resolved to prevent
// them from being tampered with. See crbug.com/771365 for details.
PROTECTED_MEMORY_SECTION base::ProtectedMemory<GetDisplayPlatformFunc>
    g_angle_get_platform;
PROTECTED_MEMORY_SECTION base::ProtectedMemory<ResetDisplayPlatformFunc>
    g_angle_reset_platform;

double ANGLEPlatformImpl_currentTime(PlatformMethods* platform) {
  return base::Time::Now().ToDoubleT();
}

double ANGLEPlatformImpl_monotonicallyIncreasingTime(
    PlatformMethods* platform) {
  return (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
}

const unsigned char* ANGLEPlatformImpl_getTraceCategoryEnabledFlag(
    PlatformMethods* platform,
    const char* category_group) {
  return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
}

void ANGLEPlatformImpl_logError(PlatformMethods* platform,
                                const char* errorMessage) {
  LOG(ERROR) << errorMessage;
}

void ANGLEPlatformImpl_logWarning(PlatformMethods* platform,
                                  const char* warningMessage) {
  LOG(WARNING) << warningMessage;
}

TraceEventHandle ANGLEPlatformImpl_addTraceEvent(
    PlatformMethods* platform,
    char phase,
    const unsigned char* category_group_enabled,
    const char* name,
    unsigned long long id,
    double timestamp,
    int num_args,
    const char** arg_names,
    const unsigned char* arg_types,
    const unsigned long long* arg_values,
    unsigned char flags) {
  base::TimeTicks timestamp_tt =
      base::TimeTicks() + base::TimeDelta::FromSecondsD(timestamp);
  base::trace_event::TraceArguments args(num_args, arg_names, arg_types,
                                         arg_values);
  base::trace_event::TraceEventHandle handle =
      TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
          phase, category_group_enabled, name,
          trace_event_internal::kGlobalScope, id, trace_event_internal::kNoId,
          base::PlatformThread::CurrentId(), timestamp_tt, &args, flags);
  TraceEventHandle result;
  memcpy(&result, &handle, sizeof(result));
  return result;
}

void ANGLEPlatformImpl_updateTraceEventDuration(
    PlatformMethods* platform,
    const unsigned char* category_group_enabled,
    const char* name,
    TraceEventHandle handle) {
  base::trace_event::TraceEventHandle trace_event_handle;
  memcpy(&trace_event_handle, &handle, sizeof(handle));
  TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled, name,
                                              trace_event_handle);
}

void ANGLEPlatformImpl_histogramCustomCounts(PlatformMethods* platform,
                                             const char* name,
                                             int sample,
                                             int min,
                                             int max,
                                             int bucket_count) {
  // Copied from histogram macro, but without the static variable caching
  // the histogram because name is dynamic.
  base::HistogramBase* counter = base::Histogram::FactoryGet(
      name, min, max, bucket_count,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->Add(sample);
}

void ANGLEPlatformImpl_histogramEnumeration(PlatformMethods* platform,
                                            const char* name,
                                            int sample,
                                            int boundary_value) {
  // Copied from histogram macro, but without the static variable caching
  // the histogram because name is dynamic.
  base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
      name, 1, boundary_value, boundary_value + 1,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  counter->Add(sample);
}

void ANGLEPlatformImpl_histogramSparse(PlatformMethods* platform,
                                       const char* name,
                                       int sample) {
  base::UmaHistogramSparse(name, sample);
}

void ANGLEPlatformImpl_histogramBoolean(PlatformMethods* platform,
                                        const char* name,
                                        bool sample) {
  ANGLEPlatformImpl_histogramEnumeration(platform, name, sample ? 1 : 0, 2);
}

}  // anonymous namespace

bool InitializePlatform(EGLDisplay display) {
  {
    auto writer = base::AutoWritableMemory::Create(g_angle_get_platform);
    *g_angle_get_platform = reinterpret_cast<GetDisplayPlatformFunc>(
        eglGetProcAddress("ANGLEGetDisplayPlatform"));
  }

  if (!*g_angle_get_platform)
    return false;

  // Save the pointer to the destroy function here to avoid crash.
  {
    auto writer = base::AutoWritableMemory::Create(g_angle_reset_platform);
    *g_angle_reset_platform = reinterpret_cast<ResetDisplayPlatformFunc>(
        eglGetProcAddress("ANGLEResetDisplayPlatform"));
  }

  PlatformMethods* platformMethods = nullptr;
  if (!base::UnsanitizedCfiCall(g_angle_get_platform)(
          static_cast<EGLDisplayType>(display), g_PlatformMethodNames,
          g_NumPlatformMethods, nullptr, &platformMethods))
    return false;
  platformMethods->currentTime = ANGLEPlatformImpl_currentTime;
  platformMethods->addTraceEvent = ANGLEPlatformImpl_addTraceEvent;
  platformMethods->currentTime = ANGLEPlatformImpl_currentTime;
  platformMethods->getTraceCategoryEnabledFlag =
      ANGLEPlatformImpl_getTraceCategoryEnabledFlag;
  platformMethods->histogramBoolean = ANGLEPlatformImpl_histogramBoolean;
  platformMethods->histogramCustomCounts =
      ANGLEPlatformImpl_histogramCustomCounts;
  platformMethods->histogramEnumeration =
      ANGLEPlatformImpl_histogramEnumeration;
  platformMethods->histogramSparse = ANGLEPlatformImpl_histogramSparse;
  platformMethods->logError = ANGLEPlatformImpl_logError;
  platformMethods->logWarning = ANGLEPlatformImpl_logWarning;
  platformMethods->monotonicallyIncreasingTime =
      ANGLEPlatformImpl_monotonicallyIncreasingTime;
  platformMethods->updateTraceEventDuration =
      ANGLEPlatformImpl_updateTraceEventDuration;
  return true;
}

void ResetPlatform(EGLDisplay display) {
  if (!*g_angle_reset_platform)
    return;
  base::UnsanitizedCfiCall(g_angle_reset_platform)(
      static_cast<EGLDisplayType>(display));
  {
    auto writer = base::AutoWritableMemory::Create(g_angle_reset_platform);
    *g_angle_reset_platform = nullptr;
  }
}

}  // namespace angle
