1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrTracing_DEFINED
9#define GrTracing_DEFINED
10
11#include "GrDrawTarget.h"
12#include "GrGpu.h"
13#include "GrInOrderDrawBuffer.h"
14#include "GrTraceMarker.h"
15#include "SkTraceEvent.h"
16
17/**
18 * Marker generation class used for adding and removing markers around code blocks
19 */
20class GrGpuTraceMarkerGenerator : public ::SkNoncopyable {
21public:
22    GrGpuTraceMarkerGenerator(GrDrawTarget* target) : fTarget(target) {}
23
24    ~GrGpuTraceMarkerGenerator() {
25        if (fTraceMarker.isValid()) {
26            fTarget->removeGpuTraceMarker(fTraceMarker.get());
27        }
28    }
29
30    void initialize(const char* marker_str, int* marker_counter) {
31        GrGpuTraceMarker* traceMarker = fTraceMarker.init();
32        traceMarker->fMarker = marker_str;
33        traceMarker->fID = *marker_counter;
34        fTarget->addGpuTraceMarker(traceMarker);
35    }
36
37private:
38    GrDrawTarget* fTarget;
39    SkTLazy<GrGpuTraceMarker> fTraceMarker;
40};
41
42class GrGpuTraceMarkerGeneratorContext : public ::SkNoncopyable {
43public:
44    GrGpuTraceMarkerGeneratorContext(GrContext* context) : fContext(context) {}
45
46    ~GrGpuTraceMarkerGeneratorContext() {
47        if (fTraceMarker.isValid()) {
48            fContext->removeGpuTraceMarker(fTraceMarker.get());
49        }
50    }
51
52    void initialize(const char* marker_str, int* marker_counter) {
53        GrGpuTraceMarker* traceMarker = fTraceMarker.init();
54        traceMarker->fMarker = marker_str;
55        traceMarker->fID = *marker_counter;
56        fContext->addGpuTraceMarker(traceMarker);
57    }
58
59private:
60    GrContext* fContext;
61    SkTLazy<GrGpuTraceMarker> fTraceMarker;
62};
63
64/**
65 * GR_CREATE_TRACE_MARKER will place begin and end trace markers for both
66 * cpu and gpu (if gpu tracing enabled) for the current scope.
67 * marker is of type const char* and target is of type GrDrawTarget*
68 */
69#define GR_CREATE_TRACE_MARKER(name, target)                              \
70    static const char* SK_MACRO_APPEND_LINE(static_name) = name;          \
71    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                    \
72    INTERNAL_GR_CREATE_TRACE_MARKER(SK_MACRO_APPEND_LINE(static_name),    \
73                                    SK_MACRO_APPEND_LINE(name_counter),   \
74                                    target)                               \
75    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                   \
76
77#define INTERNAL_GR_CREATE_TRACE_MARKER(name, name_counter, target)       \
78    GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                \
79    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,              \
80                 "id", name_counter)                                      \
81
82#define GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)            \
83    GrGpuTraceMarkerGenerator SK_MACRO_APPEND_LINE(TMG)(target);          \
84    if (target->isGpuTracingEnabled()) {                                  \
85        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);        \
86    }                                                                     \
87
88#define GR_CREATE_TRACE_MARKER_CONTEXT(name, context)                     \
89    static const char* SK_MACRO_APPEND_LINE(static_name) = name;          \
90    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                    \
91    INTERNAL_GR_CREATE_TRACE_MARKER_C(SK_MACRO_APPEND_LINE(static_name),  \
92                                    SK_MACRO_APPEND_LINE(name_counter),   \
93                                    context)                              \
94    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                   \
95
96#define INTERNAL_GR_CREATE_TRACE_MARKER_C(name, name_counter, context)    \
97    GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)             \
98    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,              \
99                 "id", name_counter)                                      \
100
101#define GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)         \
102    GrGpuTraceMarkerGeneratorContext SK_MACRO_APPEND_LINE(TMG)(context);  \
103    if (context->isGpuTracingEnabled()) {                                 \
104        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);        \
105    }                                                                     \
106
107
108#endif
109