1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "CallTracerTypes.h"
29#include "CanvasBase.h"
30#include "InspectorCanvas.h"
31#include "InspectorWebAgentBase.h"
32#include "Timer.h"
33#include <JavaScriptCore/InspectorBackendDispatchers.h>
34#include <JavaScriptCore/InspectorFrontendDispatchers.h>
35#include <wtf/HashMap.h>
36#include <wtf/RefPtr.h>
37#include <wtf/Vector.h>
38#include <wtf/text/WTFString.h>
39
40#if ENABLE(WEBGL)
41#include "InspectorShaderProgram.h"
42#endif
43
44namespace Inspector {
45class InjectedScriptManager;
46}
47
48namespace WebCore {
49
50class CanvasRenderingContext;
51#if ENABLE(WEBGL)
52class WebGLProgram;
53class WebGLRenderingContextBase;
54#endif
55
56typedef String ErrorString;
57
58class InspectorCanvasAgent final : public InspectorAgentBase, public CanvasObserver, public Inspector::CanvasBackendDispatcherHandler {
59 WTF_MAKE_NONCOPYABLE(InspectorCanvasAgent);
60 WTF_MAKE_FAST_ALLOCATED;
61public:
62 explicit InspectorCanvasAgent(PageAgentContext&);
63 virtual ~InspectorCanvasAgent() = default;
64
65 void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
66 void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
67 void discardAgent() override;
68
69 // CanvasBackendDispatcherHandler
70 void enable(ErrorString&) override;
71 void disable(ErrorString&) override;
72 void requestNode(ErrorString&, const String& canvasId, int* nodeId) override;
73 void requestContent(ErrorString&, const String& canvasId, String* content) override;
74 void requestCSSCanvasClientNodes(ErrorString&, const String& canvasId, RefPtr<JSON::ArrayOf<int>>&) override;
75 void resolveCanvasContext(ErrorString&, const String& canvasId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) override;
76 void setRecordingAutoCaptureFrameCount(ErrorString&, int count) override;
77 void startRecording(ErrorString&, const String& canvasId, const int* frameCount, const int* memoryLimit) override;
78 void stopRecording(ErrorString&, const String& canvasId) override;
79 void requestShaderSource(ErrorString&, const String& programId, const String& shaderType, String*) override;
80 void updateShader(ErrorString&, const String& programId, const String& shaderType, const String& source) override;
81 void setShaderProgramDisabled(ErrorString&, const String& programId, bool disabled) override;
82 void setShaderProgramHighlighted(ErrorString&, const String& programId, bool highlighted) override;
83
84 // InspectorInstrumentation
85 void frameNavigated(Frame&);
86 void didChangeCSSCanvasClientNodes(CanvasBase&);
87 void didCreateCanvasRenderingContext(CanvasRenderingContext&);
88 void willDestroyCanvasRenderingContext(CanvasRenderingContext&);
89 void didChangeCanvasMemory(CanvasRenderingContext&);
90 void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
91 void didFinishRecordingCanvasFrame(CanvasRenderingContext&, bool forceDispatch = false);
92 void consoleStartRecordingCanvas(CanvasRenderingContext&, JSC::ExecState&, JSC::JSObject* options);
93#if ENABLE(WEBGL)
94 void didEnableExtension(WebGLRenderingContextBase&, const String&);
95 void didCreateProgram(WebGLRenderingContextBase&, WebGLProgram&);
96 void willDeleteProgram(WebGLProgram&);
97 bool isShaderProgramDisabled(WebGLProgram&);
98 bool isShaderProgramHighlighted(WebGLProgram&);
99#endif
100
101 // CanvasObserver
102 void canvasChanged(CanvasBase&, const FloatRect&) override;
103 void canvasResized(CanvasBase&) override { }
104 void canvasDestroyed(CanvasBase&) override;
105
106private:
107 struct RecordingOptions {
108 Optional<long> frameCount;
109 Optional<long> memoryLimit;
110 Optional<String> name;
111 };
112 void startRecording(InspectorCanvas&, Inspector::Protocol::Recording::Initiator, RecordingOptions&& = { });
113
114 void canvasDestroyedTimerFired();
115 void clearCanvasData();
116 InspectorCanvas& bindCanvas(CanvasRenderingContext&, bool captureBacktrace);
117 String unbindCanvas(InspectorCanvas&);
118 RefPtr<InspectorCanvas> assertInspectorCanvas(ErrorString&, const String& identifier);
119 RefPtr<InspectorCanvas> findInspectorCanvas(CanvasRenderingContext&);
120#if ENABLE(WEBGL)
121 String unbindProgram(InspectorShaderProgram&);
122 RefPtr<InspectorShaderProgram> assertInspectorProgram(ErrorString&, const String& identifier);
123 RefPtr<InspectorShaderProgram> findInspectorProgram(WebGLProgram&);
124#endif
125
126 std::unique_ptr<Inspector::CanvasFrontendDispatcher> m_frontendDispatcher;
127 RefPtr<Inspector::CanvasBackendDispatcher> m_backendDispatcher;
128
129 Inspector::InjectedScriptManager& m_injectedScriptManager;
130 Page& m_inspectedPage;
131
132 HashMap<String, RefPtr<InspectorCanvas>> m_identifierToInspectorCanvas;
133#if ENABLE(WEBGL)
134 HashMap<String, RefPtr<InspectorShaderProgram>> m_identifierToInspectorProgram;
135#endif
136 Vector<String> m_removedCanvasIdentifiers;
137
138 Optional<size_t> m_recordingAutoCaptureFrameCount;
139
140 Timer m_canvasDestroyedTimer;
141};
142
143} // namespace WebCore
144