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    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target)
71
72#define GR_CREATE_TRACE_MARKER1(name, target, arg1_name, arg1_val)                \
73    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target, arg1_name, arg1_val)
74
75#define INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target, ...)                 \
76    static const char* SK_MACRO_APPEND_LINE(static_name) = name;                  \
77    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                            \
78    INTERNAL_GR_CREATE_TRACE_MARKER(SK_MACRO_APPEND_LINE(static_name),            \
79                                    SK_MACRO_APPEND_LINE(name_counter),           \
80                                    target, ##__VA_ARGS__)                        \
81    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));
82
83#define INTERNAL_GR_CREATE_TRACE_MARKER(name, name_counter, target, ...)          \
84    GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                        \
85    INTERNAL_TRACE_EVENT_ADD_SCOPED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,   \
86                       "id", name_counter, ##__VA_ARGS__);
87
88#define GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                     \
89    GrGpuTraceMarkerGenerator SK_MACRO_APPEND_LINE(TMG)(target);                   \
90    bool SK_MACRO_APPEND_LINE(gpuTracingEnabled);                                  \
91    TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),      \
92                                        &SK_MACRO_APPEND_LINE(gpuTracingEnabled)); \
93    if (SK_MACRO_APPEND_LINE(gpuTracingEnabled)) {                                 \
94        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);                 \
95    }
96
97
98#define GR_CREATE_TRACE_MARKER_CONTEXT(name, context)                             \
99    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context)
100
101#define GR_CREATE_TRACE_MARKER_CONTEXT1(name, context, arg1_name, arg1_val)       \
102    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context, arg1_name, arg1_val)
103
104#define INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context, ...)              \
105    static const char* SK_MACRO_APPEND_LINE(static_name) = name;                  \
106    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                            \
107    INTERNAL_GR_CREATE_TRACE_MARKER_C(SK_MACRO_APPEND_LINE(static_name),          \
108                                      SK_MACRO_APPEND_LINE(name_counter),         \
109                                      context, ##__VA_ARGS__)                     \
110    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));
111
112#define INTERNAL_GR_CREATE_TRACE_MARKER_C(name, name_counter, context, ...)       \
113    GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)                     \
114    INTERNAL_TRACE_EVENT_ADD_SCOPED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,   \
115                                    "id", name_counter, ##__VA_ARGS__);
116
117#define GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)                  \
118    GrGpuTraceMarkerGeneratorContext SK_MACRO_APPEND_LINE(TMG)(context);           \
119    bool SK_MACRO_APPEND_LINE(gpuTracingEnabled);                                  \
120    TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),      \
121                                        &SK_MACRO_APPEND_LINE(gpuTracingEnabled)); \
122    if (SK_MACRO_APPEND_LINE(gpuTracingEnabled)) {                                 \
123        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);                 \
124    }
125
126#endif
127