1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "GLContextProvider.h"
10 #include "ScopedGLHelpers.h"
12 #include "GLBlitHelper.h"
13 #include "GLReadTexImageHelper.h"
14 #include "GLLibraryEGL.h"
15 #include "mozilla/gfx/Logging.h"
16 #include "mozilla/layers/LayersSurfaces.h"
18 using namespace mozilla
;
19 using namespace mozilla::gl
;
21 namespace mozilla::layers
{
23 static RefPtr
<GLContext
> sSnapshotContext
;
25 nsresult
GLImage::ReadIntoBuffer(uint8_t* aData
, int32_t aStride
,
26 const gfx::IntSize
& aSize
,
27 gfx::SurfaceFormat aFormat
) {
28 MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
30 if (!sSnapshotContext
) {
31 nsCString discardFailureId
;
32 sSnapshotContext
= GLContextProvider::CreateHeadless({}, &discardFailureId
);
33 if (!sSnapshotContext
) {
34 NS_WARNING("Failed to create snapshot GLContext");
35 return NS_ERROR_FAILURE
;
39 sSnapshotContext
->MakeCurrent();
40 ScopedTexture
scopedTex(sSnapshotContext
);
41 ScopedBindTexture
boundTex(sSnapshotContext
, scopedTex
.Texture());
43 sSnapshotContext
->fTexImage2D(LOCAL_GL_TEXTURE_2D
, 0, LOCAL_GL_RGBA
,
44 aSize
.width
, aSize
.height
, 0, LOCAL_GL_RGBA
,
45 LOCAL_GL_UNSIGNED_BYTE
, nullptr);
47 ScopedFramebufferForTexture
autoFBForTex(sSnapshotContext
,
49 if (!autoFBForTex
.IsComplete()) {
51 << "GetAsSourceSurface: ScopedFramebufferForTexture failed.";
52 return NS_ERROR_FAILURE
;
55 const gl::OriginPos destOrigin
= gl::OriginPos::TopLeft
;
57 const ScopedBindFramebuffer
bindFB(sSnapshotContext
, autoFBForTex
.FB());
58 if (!sSnapshotContext
->BlitHelper()->BlitImageToFramebuffer(this, aSize
,
60 return NS_ERROR_FAILURE
;
64 ScopedBindFramebuffer
bind(sSnapshotContext
, autoFBForTex
.FB());
65 ReadPixelsIntoBuffer(sSnapshotContext
, aData
, aStride
, aSize
, aFormat
);
69 already_AddRefed
<gfx::SourceSurface
> GLImage::GetAsSourceSurface() {
70 MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
72 gfx::IntSize size
= GetSize();
73 auto format
= gfx::SurfaceFormat::B8G8R8A8
;
74 RefPtr
<gfx::DataSourceSurface
> dest
=
75 gfx::Factory::CreateDataSourceSurface(size
, format
);
76 if (NS_WARN_IF(!dest
)) {
80 gfx::DataSourceSurface::ScopedMap
map(dest
, gfx::DataSourceSurface::WRITE
);
81 if (NS_WARN_IF(!map
.IsMapped())) {
85 nsresult rv
= ReadIntoBuffer(map
.GetData(), map
.GetStride(), size
, format
);
86 if (NS_WARN_IF(NS_FAILED(rv
))) {
93 nsresult
GLImage::BuildSurfaceDescriptorBuffer(
94 SurfaceDescriptorBuffer
& aSdBuffer
, BuildSdbFlags aFlags
,
95 const std::function
<MemoryOrShmem(uint32_t)>& aAllocate
) {
96 gfx::IntSize size
= GetSize();
97 auto format
= gfx::SurfaceFormat::B8G8R8A8
;
99 uint8_t* buffer
= nullptr;
101 nsresult rv
= AllocateSurfaceDescriptorBufferRgb(
102 size
, format
, buffer
, aSdBuffer
, stride
, aAllocate
);
103 if (NS_WARN_IF(NS_FAILED(rv
))) {
107 return ReadIntoBuffer(buffer
, stride
, size
, format
);
110 #ifdef MOZ_WIDGET_ANDROID
111 SurfaceTextureImage::SurfaceTextureImage(
112 AndroidSurfaceTextureHandle aHandle
, const gfx::IntSize
& aSize
,
113 bool aContinuous
, gl::OriginPos aOriginPos
, bool aHasAlpha
,
114 bool aForceBT709ColorSpace
, Maybe
<gfx::Matrix4x4
> aTransformOverride
)
115 : GLImage(ImageFormat::SURFACE_TEXTURE
),
118 mContinuous(aContinuous
),
119 mOriginPos(aOriginPos
),
120 mHasAlpha(aHasAlpha
),
121 mForceBT709ColorSpace(aForceBT709ColorSpace
),
122 mTransformOverride(aTransformOverride
) {
126 Maybe
<SurfaceDescriptor
> SurfaceTextureImage::GetDesc() {
127 SurfaceDescriptor sd
= SurfaceTextureDescriptor(
129 mHasAlpha
? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8
,
130 mForceBT709ColorSpace
, false /* NOT continuous */, mTransformOverride
);
135 } // namespace mozilla::layers