1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/private/SkOnce.h"
9cb93a386Sopenharmony_ci#include "include/utils/SkEventTracer.h"
10cb93a386Sopenharmony_ci#include <atomic>
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#include <stdlib.h>
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciclass SkDefaultEventTracer : public SkEventTracer {
15cb93a386Sopenharmony_ci    SkEventTracer::Handle
16cb93a386Sopenharmony_ci        addTraceEvent(char phase,
17cb93a386Sopenharmony_ci                      const uint8_t* categoryEnabledFlag,
18cb93a386Sopenharmony_ci                      const char* name,
19cb93a386Sopenharmony_ci                      uint64_t id,
20cb93a386Sopenharmony_ci                      int numArgs,
21cb93a386Sopenharmony_ci                      const char** argNames,
22cb93a386Sopenharmony_ci                      const uint8_t* argTypes,
23cb93a386Sopenharmony_ci                      const uint64_t* argValues,
24cb93a386Sopenharmony_ci                      uint8_t flags) override { return 0; }
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci    void
27cb93a386Sopenharmony_ci        updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
28cb93a386Sopenharmony_ci                                 const char* name,
29cb93a386Sopenharmony_ci                                 SkEventTracer::Handle handle) override {}
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci    const uint8_t* getCategoryGroupEnabled(const char* name) override {
32cb93a386Sopenharmony_ci        static uint8_t no = 0;
33cb93a386Sopenharmony_ci        return &no;
34cb93a386Sopenharmony_ci    }
35cb93a386Sopenharmony_ci    const char* getCategoryGroupName(
36cb93a386Sopenharmony_ci      const uint8_t* categoryEnabledFlag) override {
37cb93a386Sopenharmony_ci        static const char* stub = "stub";
38cb93a386Sopenharmony_ci        return stub;
39cb93a386Sopenharmony_ci    }
40cb93a386Sopenharmony_ci};
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci// We prefer gUserTracer if it's been set, otherwise we fall back on a default tracer;
43cb93a386Sopenharmony_cistatic std::atomic<SkEventTracer*> gUserTracer{nullptr};
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_cibool SkEventTracer::SetInstance(SkEventTracer* tracer) {
46cb93a386Sopenharmony_ci    SkEventTracer* expected = nullptr;
47cb93a386Sopenharmony_ci    if (!gUserTracer.compare_exchange_strong(expected, tracer)) {
48cb93a386Sopenharmony_ci        delete tracer;
49cb93a386Sopenharmony_ci        return false;
50cb93a386Sopenharmony_ci    }
51cb93a386Sopenharmony_ci    atexit([]() { delete gUserTracer.load(); });
52cb93a386Sopenharmony_ci    return true;
53cb93a386Sopenharmony_ci}
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ciSkEventTracer* SkEventTracer::GetInstance() {
56cb93a386Sopenharmony_ci    if (auto tracer = gUserTracer.load(std::memory_order_acquire)) {
57cb93a386Sopenharmony_ci        return tracer;
58cb93a386Sopenharmony_ci    }
59cb93a386Sopenharmony_ci    static SkOnce once;
60cb93a386Sopenharmony_ci    static SkDefaultEventTracer* defaultTracer;
61cb93a386Sopenharmony_ci    once([] { defaultTracer = new SkDefaultEventTracer; });
62cb93a386Sopenharmony_ci    return defaultTracer;
63cb93a386Sopenharmony_ci}
64