Backed out changeset 7b83373f7a9e (bug 1883860) for causing build bustages @ caps...
[gecko.git] / dom / canvas / SourceSurfaceWebgl.cpp
blob21a5045eaa93ee588463061f97d4e90144719104
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/. */
7 #include "DrawTargetWebglInternal.h"
8 #include "SourceSurfaceWebgl.h"
10 namespace mozilla::gfx {
12 SourceSurfaceWebgl::SourceSurfaceWebgl(DrawTargetWebgl* aDT)
13 : mFormat(aDT->GetFormat()),
14 mSize(aDT->GetSize()),
15 mDT(aDT),
16 mSharedContext(aDT->mSharedContext) {}
18 SourceSurfaceWebgl::SourceSurfaceWebgl(
19 const RefPtr<SharedContextWebgl>& aSharedContext)
20 : mSharedContext(aSharedContext) {}
22 SourceSurfaceWebgl::~SourceSurfaceWebgl() {
23 if (mHandle) {
24 // Signal that the texture handle is not being used now.
25 mHandle->ClearSurface();
29 // Read back the contents of the target or texture handle for data use.
30 inline bool SourceSurfaceWebgl::EnsureData() {
31 if (mData) {
32 return true;
34 if (!mDT) {
35 // Assume that the target changed, so there should be a texture handle
36 // holding a copy. Try to read data from the copy since we can't read
37 // from the target.
38 if (!mHandle || !mSharedContext) {
39 return false;
41 mData = mSharedContext->ReadSnapshot(mHandle);
42 } else {
43 mData = mDT->ReadSnapshot();
45 return !!mData;
48 uint8_t* SourceSurfaceWebgl::GetData() {
49 if (!EnsureData()) {
50 return nullptr;
52 return mData->GetData();
55 int32_t SourceSurfaceWebgl::Stride() {
56 if (!EnsureData()) {
57 return 0;
59 return mData->Stride();
62 bool SourceSurfaceWebgl::Map(MapType aType, MappedSurface* aMappedSurface) {
63 if (!EnsureData()) {
64 return false;
66 return mData->Map(aType, aMappedSurface);
69 void SourceSurfaceWebgl::Unmap() {
70 if (mData) {
71 mData->Unmap();
75 // Handler for when the owner DrawTargetWebgl is about to modify its internal
76 // framebuffer, and so this snapshot must be copied into a new texture, if
77 // possible, or read back into data, if necessary, to preserve this particular
78 // version of the framebuffer.
79 void SourceSurfaceWebgl::DrawTargetWillChange(bool aNeedHandle) {
80 MOZ_ASSERT(mDT);
81 // Only try to copy into a new texture handle if we don't already have data.
82 // However, we still might need to immediately draw this snapshot to a WebGL
83 // target, which would require a subsequent upload, so also copy into a new
84 // handle even if we already have data in that case since it is faster than
85 // uploading.
86 if ((!mData || aNeedHandle) && !mHandle) {
87 // Prefer copying the framebuffer to a texture if possible.
88 mHandle = mDT->CopySnapshot();
89 if (mHandle) {
90 // Link this surface to the handle.
91 mHandle->SetSurface(this);
92 } else {
93 // If that fails, then try to just read the data to a surface.
94 EnsureData();
97 mDT = nullptr;
100 // Handler for when the owner DrawTargetWebgl is itself being destroyed and
101 // needs to transfer ownership of its internal backing texture to the snapshot.
102 void SourceSurfaceWebgl::GiveTexture(RefPtr<TextureHandle> aHandle) {
103 // If we get here, then the target still points to this surface as its
104 // snapshot and needs to hand off its backing texture before it is destroyed.
105 MOZ_ASSERT(mDT);
106 MOZ_ASSERT(!mHandle);
107 mHandle = aHandle.forget();
108 mHandle->SetSurface(this);
109 mDT = nullptr;
112 void SourceSurfaceWebgl::SetHandle(TextureHandle* aHandle) {
113 MOZ_ASSERT(!mHandle);
114 mFormat = aHandle->GetFormat();
115 mSize = aHandle->GetSize();
116 mHandle = aHandle;
117 mHandle->SetSurface(this);
120 // Handler for when the owner DrawTargetWebgl is destroying the cached texture
121 // handle that has been allocated for this snapshot.
122 void SourceSurfaceWebgl::OnUnlinkTexture(SharedContextWebgl* aContext) {
123 // If we get here, then we must have copied a snapshot, which only happens
124 // if the target changed.
125 MOZ_ASSERT(!mDT);
126 // If the snapshot was mapped before the target changed, we may have read
127 // data instead of holding a copied texture handle. If subsequently we then
128 // try to draw with this snapshot, we might have allocated an external texture
129 // handle in the texture cache that still links to this snapshot and can cause
130 // us to end up here inside OnUnlinkTexture.
131 MOZ_ASSERT(mHandle || mData);
132 if (!mData) {
133 mData = aContext->ReadSnapshot(mHandle);
135 mHandle = nullptr;
138 already_AddRefed<SourceSurface> SourceSurfaceWebgl::ExtractSubrect(
139 const IntRect& aRect) {
140 // Ensure we have a texture source available to extract from.
141 if (!(mDT || (mHandle && mSharedContext)) || aRect.IsEmpty() ||
142 !GetRect().Contains(aRect)) {
143 return nullptr;
145 RefPtr<TextureHandle> subHandle;
146 RefPtr<SharedContextWebgl> sharedContext;
147 if (mDT) {
148 // If this is still a snapshot linked to a target, then copy from the
149 // target.
150 subHandle = mDT->CopySnapshot(aRect);
151 if (!subHandle) {
152 return nullptr;
154 sharedContext = mDT->mSharedContext;
155 } else {
156 // Otherwise, we have a handle, but we need to verify it is still linked to
157 // a valid context.
158 sharedContext = mSharedContext;
159 if (!sharedContext) {
160 return nullptr;
162 // Try to copy directly from the handle using the context.
163 subHandle = sharedContext->CopySnapshot(aRect, mHandle);
164 if (!subHandle) {
165 return nullptr;
168 RefPtr<SourceSurfaceWebgl> surface = new SourceSurfaceWebgl(sharedContext);
169 surface->SetHandle(subHandle);
170 return surface.forget();
173 } // namespace mozilla::gfx