1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
7 #include "LayerScope.h"
9 #include "Composer2D.h"
11 #include "mozilla/TimeStamp.h"
12 #include "mozilla/Preferences.h"
13 #include "mozilla/Endian.h"
14 #include "TexturePoolOGL.h"
15 #include "mozilla/layers/CompositorOGL.h"
16 #include "mozilla/layers/LayerManagerComposite.h"
17 #include "mozilla/layers/TextureHostOGL.h"
20 #include "gfxContext.h"
23 #include "nsIWidget.h"
25 #include "GLContext.h"
26 #include "GLContextProvider.h"
27 #include "GLReadTexImageHelper.h"
29 #include "nsIServiceManager.h"
30 #include "nsIConsoleService.h"
33 #include "mozilla/LinkedList.h"
34 #include "mozilla/Base64.h"
35 #include "mozilla/SHA1.h"
36 #include "mozilla/StaticPtr.h"
37 #include "nsThreadUtils.h"
38 #include "nsISocketTransport.h"
39 #include "nsIServerSocket.h"
40 #include "nsReadLine.h"
42 #include "nsIOutputStream.h"
43 #include "nsIAsyncInputStream.h"
44 #include "nsIEventTarget.h"
45 #include "nsProxyRelease.h"
47 // Undo the damage done by mozzconf.h
49 #include "mozilla/Compression.h"
51 // Protocol buffer (generated automatically)
52 #include "protobuf/LayerScopePacket.pb.h"
57 using namespace mozilla::Compression
;
58 using namespace mozilla::gfx
;
59 using namespace mozilla::gl
;
60 using namespace mozilla
;
61 using namespace layerscope
;
63 class DebugDataSender
;
66 /* This class handle websocket protocol which included
67 * handshake and data frame's header
69 class LayerScopeWebSocketHandler
: public nsIInputStreamCallback
{
71 NS_DECL_THREADSAFE_ISUPPORTS
73 enum SocketStateType
{
79 LayerScopeWebSocketHandler()
84 virtual ~LayerScopeWebSocketHandler()
87 mTransport
->Close(NS_OK
);
92 void OpenStream(nsISocketTransport
* aTransport
) {
93 MOZ_ASSERT(aTransport
);
95 mTransport
= aTransport
;
96 mTransport
->OpenOutputStream(nsITransport::OPEN_BLOCKING
,
99 getter_AddRefs(mOutputStream
));
101 nsCOMPtr
<nsIInputStream
> debugInputStream
;
102 mTransport
->OpenInputStream(0,
105 getter_AddRefs(debugInputStream
));
106 mInputStream
= do_QueryInterface(debugInputStream
);
107 mInputStream
->AsyncWait(this, 0, 0, NS_GetCurrentThread());
110 bool WriteToStream(void *ptr
, uint32_t size
) {
111 if (mState
== NoHandshake
) {
112 // Not yet handshake, just return true in case of
113 // LayerScope remove this handle
115 } else if (mState
== HandshakeFailed
) {
119 // Generate WebSocket header
120 uint8_t wsHeader
[10];
121 int wsHeaderSize
= 0;
122 const uint8_t opcode
= 0x2;
123 wsHeader
[0] = 0x80 | (opcode
& 0x0f); // FIN + opcode;
127 } else if (size
< 65536) {
130 NetworkEndian::writeUint16(wsHeader
+ 2, size
);
134 NetworkEndian::writeUint64(wsHeader
+ 2, size
);
137 // Send WebSocket header
140 rv
= mOutputStream
->Write(reinterpret_cast<char*>(wsHeader
),
145 uint32_t written
= 0;
146 while (written
< size
) {
148 rv
= mOutputStream
->Write(reinterpret_cast<char*>(ptr
) + written
,
149 size
- written
, &cnt
);
159 // nsIInputStreamCallback
160 NS_IMETHODIMP
OnInputStreamReady(nsIAsyncInputStream
*stream
) MOZ_OVERRIDE
162 nsTArray
<nsCString
> protocolString
;
163 ReadInputStreamData(protocolString
);
165 if (WebSocketHandshake(protocolString
)) {
166 mState
= HandshakeSuccess
;
168 mState
= HandshakeFailed
;
173 void ReadInputStreamData(nsTArray
<nsCString
>& aProtocolString
)
175 nsLineBuffer
<char> lineBuffer
;
179 NS_ReadLine(mInputStream
.get(), &lineBuffer
, line
, &more
);
181 if (line
.Length() > 0) {
182 aProtocolString
.AppendElement(line
);
184 } while (more
&& line
.Length() > 0);
187 bool WebSocketHandshake(nsTArray
<nsCString
>& aProtocolString
)
190 bool isWebSocket
= false;
195 // Validate WebSocket client request.
196 if (aProtocolString
.Length() == 0)
199 // Check that the HTTP method is GET
200 const char* HTTP_METHOD
= "GET ";
201 if (strncmp(aProtocolString
[0].get(), HTTP_METHOD
, strlen(HTTP_METHOD
)) != 0) {
205 for (uint32_t i
= 1; i
< aProtocolString
.Length(); ++i
) {
206 const char* line
= aProtocolString
[i
].get();
207 const char* prop_pos
= strchr(line
, ':');
208 if (prop_pos
!= nullptr) {
209 nsCString
key(line
, prop_pos
- line
);
210 nsCString
value(prop_pos
+ 2);
211 if (key
.EqualsIgnoreCase("upgrade") &&
212 value
.EqualsIgnoreCase("websocket")) {
214 } else if (key
.EqualsIgnoreCase("sec-websocket-version")) {
216 } else if (key
.EqualsIgnoreCase("sec-websocket-key")) {
218 } else if (key
.EqualsIgnoreCase("sec-websocket-protocol")) {
228 if (!(version
.EqualsLiteral("7") ||
229 version
.EqualsLiteral("8") ||
230 version
.EqualsLiteral("13"))) {
234 if (!(protocol
.EqualsIgnoreCase("binary"))) {
238 // Client request is valid. Start to generate and send server response.
239 nsAutoCString
guid("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
242 nsCString
combined(wsKey
+ guid
);
243 sha1
.update(combined
.get(), combined
.Length());
244 uint8_t digest
[SHA1Sum::kHashSize
]; // SHA1 digests are 20 bytes long.
246 nsCString
newString(reinterpret_cast<char*>(digest
), SHA1Sum::kHashSize
);
247 Base64Encode(newString
, res
);
249 nsCString
response("HTTP/1.1 101 Switching Protocols\r\n");
250 response
.AppendLiteral("Upgrade: websocket\r\n");
251 response
.AppendLiteral("Connection: Upgrade\r\n");
252 response
.Append(nsCString("Sec-WebSocket-Accept: ") + res
+ nsCString("\r\n"));
253 response
.AppendLiteral("Sec-WebSocket-Protocol: binary\r\n\r\n");
254 uint32_t written
= 0;
255 uint32_t size
= response
.Length();
256 while (written
< size
) {
258 rv
= mOutputStream
->Write(const_cast<char*>(response
.get()) + written
,
259 size
- written
, &cnt
);
265 mOutputStream
->Flush();
270 nsCOMPtr
<nsIOutputStream
> mOutputStream
;
271 nsCOMPtr
<nsIAsyncInputStream
> mInputStream
;
272 nsCOMPtr
<nsISocketTransport
> mTransport
;
273 SocketStateType mState
;
276 NS_IMPL_ISUPPORTS(LayerScopeWebSocketHandler
, nsIInputStreamCallback
);
278 class LayerScopeWebSocketManager
{
280 LayerScopeWebSocketManager();
281 ~LayerScopeWebSocketManager();
283 void AddConnection(nsISocketTransport
*aTransport
)
285 MOZ_ASSERT(aTransport
);
286 nsRefPtr
<LayerScopeWebSocketHandler
> temp
= new LayerScopeWebSocketHandler();
287 temp
->OpenStream(aTransport
);
288 mHandlers
.AppendElement(temp
.get());
291 void RemoveConnection(uint32_t aIndex
)
293 MOZ_ASSERT(aIndex
< mHandlers
.Length());
294 mHandlers
.RemoveElementAt(aIndex
);
297 void RemoveAllConnections()
302 bool WriteAll(void *ptr
, uint32_t size
)
304 for (int32_t i
= mHandlers
.Length() - 1; i
>= 0; --i
) {
305 if (!mHandlers
[i
]->WriteToStream(ptr
, size
)) {
306 // Send failed, remove this handler
316 return (mHandlers
.Length() != 0) ? true : false;
319 void AppendDebugData(DebugGLData
*aDebugData
);
320 void CleanDebugData();
321 void DispatchDebugData();
323 nsTArray
<nsRefPtr
<LayerScopeWebSocketHandler
> > mHandlers
;
324 nsCOMPtr
<nsIThread
> mDebugSenderThread
;
325 nsRefPtr
<DebugDataSender
> mCurrentSender
;
326 nsCOMPtr
<nsIServerSocket
> mServerSocket
;
329 // Static class to create and destory LayerScopeWebSocketManager object
330 class WebSocketHelper
333 static void CreateServerSocket()
335 // Create Web Server Socket (which has to be on the main thread)
336 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
337 if (!sWebSocketManager
) {
338 sWebSocketManager
= new LayerScopeWebSocketManager();
342 static void DestroyServerSocket()
344 // Destroy Web Server Socket
345 if (sWebSocketManager
) {
346 sWebSocketManager
->RemoveAllConnections();
350 static LayerScopeWebSocketManager
* GetSocketManager()
352 return sWebSocketManager
;
356 static StaticAutoPtr
<LayerScopeWebSocketManager
> sWebSocketManager
;
359 StaticAutoPtr
<LayerScopeWebSocketManager
> WebSocketHelper::sWebSocketManager
;
362 * DebugGLData is the base class of
363 * 1. DebugGLFrameStatusData (Frame start/end packet)
364 * 2. DebugGLColorData (Color data packet)
365 * 3. DebugGLTextureData (Texture data packet)
367 class DebugGLData
: public LinkedListElement
<DebugGLData
> {
369 explicit DebugGLData(Packet::DataType aDataType
)
370 : mDataType(aDataType
)
373 virtual ~DebugGLData() { }
375 Packet::DataType
GetDataType() const { return mDataType
; }
377 virtual bool Write() = 0;
379 static bool WriteToStream(Packet
& aPacket
) {
380 if (!WebSocketHelper::GetSocketManager())
383 uint32_t size
= aPacket
.ByteSize();
384 auto data
= MakeUnique
<uint8_t[]>(size
);
385 aPacket
.SerializeToArray(data
.get(), size
);
386 return WebSocketHelper::GetSocketManager()->WriteAll(data
.get(), size
);
390 Packet::DataType mDataType
;
393 class DebugGLFrameStatusData
: public DebugGLData
396 DebugGLFrameStatusData(Packet::DataType aDataType
,
398 : DebugGLData(aDataType
),
402 explicit DebugGLFrameStatusData(Packet::DataType aDataType
)
403 : DebugGLData(aDataType
),
407 int64_t GetFrameStamp() const { return mFrameStamp
; }
409 virtual bool Write() MOZ_OVERRIDE
{
411 packet
.set_type(mDataType
);
413 FramePacket
* fp
= packet
.mutable_frame();
414 fp
->set_value(static_cast<uint64_t>(mFrameStamp
));
416 if (!WriteToStream(packet
))
425 class DebugGLTextureData
: public DebugGLData
{
427 DebugGLTextureData(GLContext
* cx
,
431 DataSourceSurface
* img
)
432 : DebugGLData(Packet::TEXTURE
),
436 mContextAddress(reinterpret_cast<intptr_t>(cx
)),
440 // DataSourceSurface may have locked buffer,
441 // so we should compress now, and then it could
442 // be unlocked outside.
446 const void* GetLayerRef() const { return mLayerRef
; }
447 GLuint
GetName() const { return mName
; }
448 GLenum
GetTextureTarget() const { return mTarget
; }
449 intptr_t GetContextAddress() const { return mContextAddress
; }
450 uint32_t GetDataSize() const { return mDatasize
; }
452 virtual bool Write() MOZ_OVERRIDE
{
453 if (!WriteToStream(mPacket
))
459 void pack(DataSourceSurface
* aImage
) {
460 mPacket
.set_type(mDataType
);
462 TexturePacket
* tp
= mPacket
.mutable_texture();
463 tp
->set_layerref(reinterpret_cast<uint64_t>(mLayerRef
));
465 tp
->set_target(mTarget
);
466 tp
->set_dataformat(LOCAL_GL_RGBA
);
467 tp
->set_glcontext(static_cast<uint64_t>(mContextAddress
));
470 tp
->set_width(aImage
->GetSize().width
);
471 tp
->set_height(aImage
->GetSize().height
);
472 tp
->set_stride(aImage
->Stride());
474 mDatasize
= aImage
->GetSize().height
* aImage
->Stride();
476 auto compresseddata
= MakeUnique
<char[]>(LZ4::maxCompressedSize(mDatasize
));
477 if (compresseddata
) {
478 int ndatasize
= LZ4::compress((char*)aImage
->GetData(),
480 compresseddata
.get());
482 mDatasize
= ndatasize
;
483 tp
->set_dataformat((1 << 16 | tp
->dataformat()));
484 tp
->set_data(compresseddata
.get(), mDatasize
);
486 NS_WARNING("Compress data failed");
487 tp
->set_data(aImage
->GetData(), mDatasize
);
490 NS_WARNING("Couldn't new compressed data.");
491 tp
->set_data(aImage
->GetData(), mDatasize
);
504 intptr_t mContextAddress
;
511 class DebugGLColorData
: public DebugGLData
{
513 DebugGLColorData(void* layerRef
,
514 const gfxRGBA
& color
,
517 : DebugGLData(Packet::COLOR
),
519 mColor(color
.Packed()),
523 const void* GetLayerRef() const { return mLayerRef
; }
524 uint32_t GetColor() const { return mColor
; }
525 const nsIntSize
& GetSize() const { return mSize
; }
527 virtual bool Write() MOZ_OVERRIDE
{
529 packet
.set_type(mDataType
);
531 ColorPacket
* cp
= packet
.mutable_color();
532 cp
->set_layerref(reinterpret_cast<uint64_t>(mLayerRef
));
533 cp
->set_color(mColor
);
534 cp
->set_width(mSize
.width
);
535 cp
->set_height(mSize
.height
);
537 if (!WriteToStream(packet
))
548 class DebugGLLayersData
: public DebugGLData
{
550 explicit DebugGLLayersData(UniquePtr
<Packet
> aPacket
)
551 : DebugGLData(Packet::LAYERS
),
552 mPacket(Move(aPacket
))
555 virtual bool Write() MOZ_OVERRIDE
{
556 mPacket
->set_type(mDataType
);
558 if (!WriteToStream(*mPacket
))
564 UniquePtr
<Packet
> mPacket
;
567 class DebugListener
: public nsIServerSocketListener
569 virtual ~DebugListener() { }
573 NS_DECL_THREADSAFE_ISUPPORTS
577 /* nsIServerSocketListener */
579 NS_IMETHODIMP
OnSocketAccepted(nsIServerSocket
*aServ
,
580 nsISocketTransport
*aTransport
)
582 if (!WebSocketHelper::GetSocketManager())
585 printf_stderr("*** LayerScope: Accepted connection\n");
586 WebSocketHelper::GetSocketManager()->AddConnection(aTransport
);
590 NS_IMETHODIMP
OnStopListening(nsIServerSocket
*aServ
,
597 NS_IMPL_ISUPPORTS(DebugListener
, nsIServerSocketListener
);
600 class DebugDataSender
: public nsIRunnable
602 virtual ~DebugDataSender() {
608 NS_DECL_THREADSAFE_ISUPPORTS
610 DebugDataSender() { }
612 void Append(DebugGLData
*d
) {
621 while ((d
= mList
.popFirst()) != nullptr)
625 /* nsIRunnable impl; send the data */
627 NS_IMETHODIMP
Run() {
631 while ((d
= mList
.popFirst()) != nullptr) {
632 UniquePtr
<DebugGLData
> cleaner(d
);
634 rv
= NS_ERROR_FAILURE
;
642 WebSocketHelper::DestroyServerSocket();
649 LinkedList
<DebugGLData
> mList
;
652 NS_IMPL_ISUPPORTS(DebugDataSender
, nsIRunnable
);
655 * LayerScope SendXXX Structure
658 * 1. SendTexturedEffect
659 * -> SendTextureSource
661 * -> SendTextureSource
666 // Sender public APIs
668 static void SendLayer(LayerComposite
* aLayer
,
672 static void SendEffectChain(gl::GLContext
* aGLContext
,
673 const EffectChain
& aEffectChain
,
677 // Sender private functions
679 static void SendColor(void* aLayerRef
,
680 const gfxRGBA
& aColor
,
683 static void SendTextureSource(GLContext
* aGLContext
,
685 TextureSourceOGL
* aSource
,
687 static void SendTexturedEffect(GLContext
* aGLContext
,
689 const TexturedEffect
* aEffect
);
690 static void SendYCbCrEffect(GLContext
* aGLContext
,
692 const EffectYCbCr
* aEffect
);
696 // ----------------------------------------------
697 // SenderHelper implementation
698 // ----------------------------------------------
700 SenderHelper::SendLayer(LayerComposite
* aLayer
,
704 MOZ_ASSERT(aLayer
&& aLayer
->GetLayer());
705 if (!aLayer
|| !aLayer
->GetLayer()) {
709 switch (aLayer
->GetLayer()->GetType()) {
710 case Layer::TYPE_COLOR
: {
712 aLayer
->GenEffectChain(effect
);
713 SenderHelper::SendEffectChain(nullptr, effect
, aWidth
, aHeight
);
716 case Layer::TYPE_IMAGE
:
717 case Layer::TYPE_CANVAS
:
718 case Layer::TYPE_THEBES
: {
719 // Get CompositableHost and Compositor
720 CompositableHost
* compHost
= aLayer
->GetCompositableHost();
721 Compositor
* comp
= compHost
->GetCompositor();
722 // Send EffectChain only for CompositorOGL
723 if (LayersBackend::LAYERS_OPENGL
== comp
->GetBackendType()) {
724 CompositorOGL
* compOGL
= static_cast<CompositorOGL
*>(comp
);
726 // Generate primary effect (lock and gen)
727 AutoLockCompositableHost
lock(compHost
);
728 aLayer
->GenEffectChain(effect
);
729 SenderHelper::SendEffectChain(compOGL
->gl(), effect
);
733 case Layer::TYPE_CONTAINER
:
740 SenderHelper::SendColor(void* aLayerRef
,
741 const gfxRGBA
& aColor
,
745 WebSocketHelper::GetSocketManager()->AppendDebugData(
746 new DebugGLColorData(aLayerRef
, aColor
, aWidth
, aHeight
));
750 SenderHelper::SendTextureSource(GLContext
* aGLContext
,
752 TextureSourceOGL
* aSource
,
755 MOZ_ASSERT(aGLContext
);
760 GLenum textureTarget
= aSource
->GetTextureTarget();
761 ShaderConfigOGL config
= ShaderConfigFromTargetAndFormat(textureTarget
,
762 aSource
->GetFormat());
763 int shaderConfig
= config
.mFeatures
;
765 aSource
->BindTexture(LOCAL_GL_TEXTURE0
, gfx::Filter::LINEAR
);
767 GLuint textureId
= 0;
768 // This is horrid hack. It assumes that aGLContext matches the context
769 // aSource has bound to.
770 if (textureTarget
== LOCAL_GL_TEXTURE_2D
) {
771 aGLContext
->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D
, &textureId
);
772 } else if (textureTarget
== LOCAL_GL_TEXTURE_EXTERNAL
) {
773 aGLContext
->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL
, &textureId
);
774 } else if (textureTarget
== LOCAL_GL_TEXTURE_RECTANGLE
) {
775 aGLContext
->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE
, &textureId
);
778 gfx::IntSize size
= aSource
->GetSize();
780 // By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
781 // texture correctly. textureId is used for tracking in DebugGLTextureData.
782 RefPtr
<DataSourceSurface
> img
=
783 aGLContext
->ReadTexImageHelper()->ReadTexImage(0, textureTarget
,
785 shaderConfig
, aFlipY
);
787 WebSocketHelper::GetSocketManager()->AppendDebugData(
788 new DebugGLTextureData(aGLContext
, aLayerRef
, textureTarget
,
793 SenderHelper::SendTexturedEffect(GLContext
* aGLContext
,
795 const TexturedEffect
* aEffect
)
797 TextureSourceOGL
* source
= aEffect
->mTexture
->AsSourceOGL();
802 SendTextureSource(aGLContext
, aLayerRef
, source
, flipY
);
806 SenderHelper::SendYCbCrEffect(GLContext
* aGLContext
,
808 const EffectYCbCr
* aEffect
)
810 TextureSource
* sourceYCbCr
= aEffect
->mTexture
;
814 const int Y
= 0, Cb
= 1, Cr
= 2;
815 TextureSourceOGL
* sourceY
= sourceYCbCr
->GetSubSource(Y
)->AsSourceOGL();
816 TextureSourceOGL
* sourceCb
= sourceYCbCr
->GetSubSource(Cb
)->AsSourceOGL();
817 TextureSourceOGL
* sourceCr
= sourceYCbCr
->GetSubSource(Cr
)->AsSourceOGL();
820 SendTextureSource(aGLContext
, aLayerRef
, sourceY
, flipY
);
821 SendTextureSource(aGLContext
, aLayerRef
, sourceCb
, flipY
);
822 SendTextureSource(aGLContext
, aLayerRef
, sourceCr
, flipY
);
826 SenderHelper::SendEffectChain(GLContext
* aGLContext
,
827 const EffectChain
& aEffectChain
,
831 const Effect
* primaryEffect
= aEffectChain
.mPrimaryEffect
;
832 switch (primaryEffect
->mType
) {
833 case EffectTypes::RGB
: {
834 const TexturedEffect
* texturedEffect
=
835 static_cast<const TexturedEffect
*>(primaryEffect
);
836 SendTexturedEffect(aGLContext
, aEffectChain
.mLayerRef
, texturedEffect
);
839 case EffectTypes::YCBCR
: {
840 const EffectYCbCr
* yCbCrEffect
=
841 static_cast<const EffectYCbCr
*>(primaryEffect
);
842 SendYCbCrEffect(aGLContext
, aEffectChain
.mLayerRef
, yCbCrEffect
);
845 case EffectTypes::SOLID_COLOR
: {
846 const EffectSolidColor
* solidColorEffect
=
847 static_cast<const EffectSolidColor
*>(primaryEffect
);
848 gfxRGBA
color(solidColorEffect
->mColor
.r
,
849 solidColorEffect
->mColor
.g
,
850 solidColorEffect
->mColor
.b
,
851 solidColorEffect
->mColor
.a
);
852 SendColor(aEffectChain
.mLayerRef
, color
, aWidth
, aHeight
);
855 case EffectTypes::COMPONENT_ALPHA
:
856 case EffectTypes::RENDER_TARGET
:
861 //const Effect* secondaryEffect = aEffectChain.mSecondaryEffects[EffectTypes::MASK];
865 // ----------------------------------------------
866 // LayerScopeWebSocketManager implementation
867 // ----------------------------------------------
868 LayerScopeWebSocketManager::LayerScopeWebSocketManager()
870 NS_NewThread(getter_AddRefs(mDebugSenderThread
));
872 mServerSocket
= do_CreateInstance(NS_SERVERSOCKET_CONTRACTID
);
873 int port
= gfxPrefs::LayerScopePort();
874 mServerSocket
->Init(port
, false, -1);
875 mServerSocket
->AsyncListen(new DebugListener
);
878 LayerScopeWebSocketManager::~LayerScopeWebSocketManager()
883 LayerScopeWebSocketManager::AppendDebugData(DebugGLData
*aDebugData
)
885 if (!mCurrentSender
) {
886 mCurrentSender
= new DebugDataSender();
889 mCurrentSender
->Append(aDebugData
);
893 LayerScopeWebSocketManager::CleanDebugData()
895 if (mCurrentSender
) {
896 mCurrentSender
->Cleanup();
901 LayerScopeWebSocketManager::DispatchDebugData()
903 mDebugSenderThread
->Dispatch(mCurrentSender
, NS_DISPATCH_NORMAL
);
904 mCurrentSender
= nullptr;
908 // ----------------------------------------------
909 // LayerScope implementation
910 // ----------------------------------------------
914 if (!gfxPrefs::LayerScopeEnabled()) {
918 // Note: The server socket has to be created on the main thread
919 WebSocketHelper::CreateServerSocket();
925 // Destroy Web Server Socket
926 WebSocketHelper::DestroyServerSocket();
930 LayerScope::SendEffectChain(gl::GLContext
* aGLContext
,
931 const EffectChain
& aEffectChain
,
935 // Protect this public function
936 if (!CheckSendable()) {
939 SenderHelper::SendEffectChain(aGLContext
, aEffectChain
, aWidth
, aHeight
);
943 LayerScope::SendLayer(LayerComposite
* aLayer
,
947 // Protect this public function
948 if (!CheckSendable()) {
951 SenderHelper::SendLayer(aLayer
, aWidth
, aHeight
);
955 LayerScope::SendLayerDump(UniquePtr
<Packet
> aPacket
)
957 // Protect this public function
958 if (!CheckSendable()) {
961 WebSocketHelper::GetSocketManager()->AppendDebugData(
962 new DebugGLLayersData(Move(aPacket
)));
966 LayerScope::CheckSendable()
968 if (!WebSocketHelper::GetSocketManager()) {
971 if (!WebSocketHelper::GetSocketManager()->IsConnected()) {
978 LayerScope::CleanLayer()
980 if (CheckSendable()) {
981 WebSocketHelper::GetSocketManager()->CleanDebugData();
985 // ----------------------------------------------
986 // LayerScopeAutoFrame implementation
987 // ----------------------------------------------
988 LayerScopeAutoFrame::LayerScopeAutoFrame(int64_t aFrameStamp
)
991 BeginFrame(aFrameStamp
);
994 LayerScopeAutoFrame::~LayerScopeAutoFrame()
1001 LayerScopeAutoFrame::BeginFrame(int64_t aFrameStamp
)
1003 if (!LayerScope::CheckSendable()) {
1007 WebSocketHelper::GetSocketManager()->AppendDebugData(
1008 new DebugGLFrameStatusData(Packet::FRAMESTART
, aFrameStamp
));
1012 LayerScopeAutoFrame::EndFrame()
1014 if (!LayerScope::CheckSendable()) {
1018 WebSocketHelper::GetSocketManager()->AppendDebugData(
1019 new DebugGLFrameStatusData(Packet::FRAMEEND
));
1020 WebSocketHelper::GetSocketManager()->DispatchDebugData();