diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java')
-rw-r--r-- | mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java new file mode 100644 index 0000000000..d533d2ad39 --- /dev/null +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoSurface.java @@ -0,0 +1,151 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.gfx; + +import static org.mozilla.geckoview.BuildConfig.DEBUG_BUILD; + +import android.os.Parcel; +import android.os.Parcelable; +import android.view.Surface; +import org.mozilla.gecko.annotation.WrapForJNI; + +public final class GeckoSurface implements Parcelable { + private static final String LOGTAG = "GeckoSurface"; + + private Surface mSurface; + private long mHandle; + private boolean mIsSingleBuffer; + private volatile boolean mIsAvailable; + private boolean mOwned = true; + private volatile boolean mIsReleased = false; + + private int mMyPid; + // Locally allocated surface/texture. Do not pass it over IPC. + private GeckoSurface mSyncSurface; + + @WrapForJNI(exceptionMode = "nsresult") + public GeckoSurface(final GeckoSurfaceTexture gst) { + mSurface = new Surface(gst); + mHandle = gst.getHandle(); + mIsSingleBuffer = gst.isSingleBuffer(); + mIsAvailable = true; + mMyPid = android.os.Process.myPid(); + } + + public GeckoSurface(final Parcel p) { + mSurface = Surface.CREATOR.createFromParcel(p); + mHandle = p.readLong(); + mIsSingleBuffer = p.readByte() == 1; + mIsAvailable = p.readByte() == 1; + mMyPid = p.readInt(); + } + + public static final Parcelable.Creator<GeckoSurface> CREATOR = + new Parcelable.Creator<GeckoSurface>() { + public GeckoSurface createFromParcel(final Parcel p) { + return new GeckoSurface(p); + } + + public GeckoSurface[] newArray(final int size) { + return new GeckoSurface[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(final Parcel out, final int flags) { + mSurface.writeToParcel(out, flags); + if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) == 0) { + // GeckoSurface can be passed across processes as a return value or + // an argument, and should always tranfers its ownership (move) to + // the receiver of parcel. On the other hand, Surface is moved only + // when passed as a return value and releases itself when corresponding + // write flags is provided. (See Surface.writeToParcel().) + // The superclass method must be called here to ensure the local instance + // is truely forgotten. + mSurface.release(); + } + mOwned = false; + + out.writeLong(mHandle); + out.writeByte((byte) (mIsSingleBuffer ? 1 : 0)); + out.writeByte((byte) (mIsAvailable ? 1 : 0)); + out.writeInt(mMyPid); + } + + public void release() { + if (mIsReleased) { + return; + } + mIsReleased = true; + + if (mSyncSurface != null) { + mSyncSurface.release(); + final GeckoSurfaceTexture gst = GeckoSurfaceTexture.lookup(mSyncSurface.getHandle()); + if (gst != null) { + gst.decrementUse(); + } + mSyncSurface = null; + } + + if (mOwned) { + mSurface.release(); + } + } + + @WrapForJNI + public long getHandle() { + return mHandle; + } + + @WrapForJNI + public Surface getSurface() { + return mSurface; + } + + @WrapForJNI + public boolean getAvailable() { + return mIsAvailable; + } + + @WrapForJNI + public boolean isReleased() { + return mIsReleased; + } + + @WrapForJNI + public void setAvailable(final boolean available) { + mIsAvailable = available; + } + + /* package */ boolean inProcess() { + return android.os.Process.myPid() == mMyPid; + } + + /* package */ SyncConfig initSyncSurface(final int width, final int height) { + if (DEBUG_BUILD) { + if (inProcess()) { + throw new AssertionError("no need for sync when allocated in process"); + } + } + if (GeckoSurfaceTexture.lookup(mHandle) != null) { + throw new AssertionError("texture#" + mHandle + " already in use."); + } + final GeckoSurfaceTexture texture = GeckoSurfaceTexture.acquire(true, mHandle); + if (texture != null) { + texture.setDefaultBufferSize(width, height); + texture.track(mHandle); + mSyncSurface = new GeckoSurface(texture); + return new SyncConfig(mHandle, mSyncSurface, width, height); + } + + return null; + } +} |