Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f68a1ed7 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6001908 from bed73cb0 to rvc-release

Change-Id: I84fec6a5802d6cf106b4417174b733d9466efe50
parents ad9e6770 bed73cb0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -67,6 +67,9 @@ cc_library_shared {
        "SurfaceComposerClient.cpp",
        "SyncFeatures.cpp",
        "view/Surface.cpp",
        "surfacetexture/SurfaceTexture.cpp",
        "surfacetexture/ImageConsumer.cpp",
        "surfacetexture/EGLConsumer.cpp",
    ],

    shared_libs: [
+309 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <gui/BufferQueueDefs.h>
#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>
#include <utils/Mutex.h>

namespace android {

class SurfaceTexture;

/*
 * EGLConsumer implements the parts of SurfaceTexture that deal with
 * textures attached to an GL context.
 */
class EGLConsumer {
public:
    EGLConsumer();

    /**
     * updateTexImage acquires the most recently queued buffer, and sets the
     * image contents of the target texture to it.
     *
     * This call may only be made while the OpenGL ES context to which the
     * target texture belongs is bound to the calling thread.
     *
     * This calls doGLFenceWait to ensure proper synchronization.
     */
    status_t updateTexImage(SurfaceTexture& st);

    /*
     * releaseTexImage releases the texture acquired in updateTexImage().
     * This is intended to be used in single buffer mode.
     *
     * This call may only be made while the OpenGL ES context to which the
     * target texture belongs is bound to the calling thread.
     */
    status_t releaseTexImage(SurfaceTexture& st);

    /**
     * detachFromContext detaches the EGLConsumer from the calling thread's
     * current OpenGL ES context.  This context must be the same as the context
     * that was current for previous calls to updateTexImage.
     *
     * Detaching a EGLConsumer from an OpenGL ES context will result in the
     * deletion of the OpenGL ES texture object into which the images were being
     * streamed.  After a EGLConsumer has been detached from the OpenGL ES
     * context calls to updateTexImage will fail returning INVALID_OPERATION
     * until the EGLConsumer is attached to a new OpenGL ES context using the
     * attachToContext method.
     */
    status_t detachFromContext(SurfaceTexture& st);

    /**
     * attachToContext attaches a EGLConsumer that is currently in the
     * 'detached' state to the current OpenGL ES context.  A EGLConsumer is
     * in the 'detached' state iff detachFromContext has successfully been
     * called and no calls to attachToContext have succeeded since the last
     * detachFromContext call.  Calls to attachToContext made on a
     * EGLConsumer that is not in the 'detached' state will result in an
     * INVALID_OPERATION error.
     *
     * The tex argument specifies the OpenGL ES texture object name in the
     * new context into which the image contents will be streamed.  A successful
     * call to attachToContext will result in this texture object being bound to
     * the texture target and populated with the image contents that were
     * current at the time of the last call to detachFromContext.
     */
    status_t attachToContext(uint32_t tex, SurfaceTexture& st);

    /**
     * onAcquireBufferLocked amends the ConsumerBase method to update the
     * mEglSlots array in addition to the ConsumerBase behavior.
     */
    void onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st);

    /**
     * onReleaseBufferLocked amends the ConsumerBase method to update the
     * mEglSlots array in addition to the ConsumerBase.
     */
    void onReleaseBufferLocked(int slot);

    /**
     * onFreeBufferLocked frees up the given buffer slot. If the slot has been
     * initialized this will release the reference to the GraphicBuffer in that
     * slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
     */
    void onFreeBufferLocked(int slotIndex);

    /**
     * onAbandonLocked amends the ConsumerBase method to clear
     * mCurrentTextureImage in addition to the ConsumerBase behavior.
     */
    void onAbandonLocked();

protected:
    struct PendingRelease {
        PendingRelease()
              : isPending(false),
                currentTexture(-1),
                graphicBuffer(),
                display(nullptr),
                fence(nullptr) {}

        bool isPending;
        int currentTexture;
        sp<GraphicBuffer> graphicBuffer;
        EGLDisplay display;
        EGLSyncKHR fence;
    };

    /**
     * This releases the buffer in the slot referenced by mCurrentTexture,
     * then updates state to refer to the BufferItem, which must be a
     * newly-acquired buffer. If pendingRelease is not null, the parameters
     * which would have been passed to releaseBufferLocked upon the successful
     * completion of the method will instead be returned to the caller, so that
     * it may call releaseBufferLocked itself later.
     */
    status_t updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease,
                                    SurfaceTexture& st);

    /**
     * Binds mTexName and the current buffer to mTexTarget.  Uses
     * mCurrentTexture if it's set, mCurrentTextureImage if not.  If the
     * bind succeeds, this calls doGLFenceWait.
     */
    status_t bindTextureImageLocked(SurfaceTexture& st);

    /**
     * Gets the current EGLDisplay and EGLContext values, and compares them
     * to mEglDisplay and mEglContext.  If the fields have been previously
     * set, the values must match; if not, the fields are set to the current
     * values.
     * The contextCheck argument is used to ensure that a GL context is
     * properly set; when set to false, the check is not performed.
     */
    status_t checkAndUpdateEglStateLocked(SurfaceTexture& st, bool contextCheck = false);

    /**
     * EglImage is a utility class for tracking and creating EGLImageKHRs. There
     * is primarily just one image per slot, but there is also special cases:
     *  - For releaseTexImage, we use a debug image (mReleasedTexImage)
     *  - After freeBuffer, we must still keep the current image/buffer
     * Reference counting EGLImages lets us handle all these cases easily while
     * also only creating new EGLImages from buffers when required.
     */
    class EglImage : public LightRefBase<EglImage> {
    public:
        EglImage(sp<GraphicBuffer> graphicBuffer);

        /**
         * createIfNeeded creates an EGLImage if required (we haven't created
         * one yet, or the EGLDisplay or crop-rect has changed).
         */
        status_t createIfNeeded(EGLDisplay display, bool forceCreate = false);

        /**
         * This calls glEGLImageTargetTexture2DOES to bind the image to the
         * texture in the specified texture target.
         */
        void bindToTextureTarget(uint32_t texTarget);

        const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; }
        const native_handle* graphicBufferHandle() {
            return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle;
        }

    private:
        // Only allow instantiation using ref counting.
        friend class LightRefBase<EglImage>;
        virtual ~EglImage();

        // createImage creates a new EGLImage from a GraphicBuffer.
        EGLImageKHR createImage(EGLDisplay dpy, const sp<GraphicBuffer>& graphicBuffer);

        // Disallow copying
        EglImage(const EglImage& rhs);
        void operator=(const EglImage& rhs);

        // mGraphicBuffer is the buffer that was used to create this image.
        sp<GraphicBuffer> mGraphicBuffer;

        // mEglImage is the EGLImage created from mGraphicBuffer.
        EGLImageKHR mEglImage;

        // mEGLDisplay is the EGLDisplay that was used to create mEglImage.
        EGLDisplay mEglDisplay;

        // mCropRect is the crop rectangle passed to EGL when mEglImage
        // was created.
        Rect mCropRect;
    };

    /**
     * doGLFenceWaitLocked inserts a wait command into the OpenGL ES command
     * stream to ensure that it is safe for future OpenGL ES commands to
     * access the current texture buffer.
     */
    status_t doGLFenceWaitLocked(SurfaceTexture& st) const;

    /**
     * syncForReleaseLocked performs the synchronization needed to release the
     * current slot from an OpenGL ES context.  If needed it will set the
     * current slot's fence to guard against a producer accessing the buffer
     * before the outstanding accesses have completed.
     */
    status_t syncForReleaseLocked(EGLDisplay dpy, SurfaceTexture& st);

    /**
     * returns a graphic buffer used when the texture image has been released
     */
    static sp<GraphicBuffer> getDebugTexImageBuffer();

    /**
     * The default consumer usage flags that EGLConsumer always sets on its
     * BufferQueue instance; these will be OR:d with any additional flags passed
     * from the EGLConsumer user. In particular, EGLConsumer will always
     * consume buffers as hardware textures.
     */
    static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;

    /**
     * mCurrentTextureImage is the EglImage/buffer of the current texture. It's
     * possible that this buffer is not associated with any buffer slot, so we
     * must track it separately in order to support the getCurrentBuffer method.
     */
    sp<EglImage> mCurrentTextureImage;

    /**
     * EGLSlot contains the information and object references that
     * EGLConsumer maintains about a BufferQueue buffer slot.
     */
    struct EglSlot {
        EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {}

        /**
         * mEglImage is the EGLImage created from mGraphicBuffer.
         */
        sp<EglImage> mEglImage;

        /**
         * mFence is the EGL sync object that must signal before the buffer
         * associated with this buffer slot may be dequeued. It is initialized
         * to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
         * on a compile-time option) set to a new sync object in updateTexImage.
         */
        EGLSyncKHR mEglFence;
    };

    /**
     * mEglDisplay is the EGLDisplay with which this EGLConsumer is currently
     * associated.  It is intialized to EGL_NO_DISPLAY and gets set to the
     * current display when updateTexImage is called for the first time and when
     * attachToContext is called.
     */
    EGLDisplay mEglDisplay;

    /**
     * mEglContext is the OpenGL ES context with which this EGLConsumer is
     * currently associated.  It is initialized to EGL_NO_CONTEXT and gets set
     * to the current GL context when updateTexImage is called for the first
     * time and when attachToContext is called.
     */
    EGLContext mEglContext;

    /**
     * mEGLSlots stores the buffers that have been allocated by the BufferQueue
     * for each buffer slot.  It is initialized to null pointers, and gets
     * filled in with the result of BufferQueue::acquire when the
     * client dequeues a buffer from a
     * slot that has not yet been used. The buffer allocated to a slot will also
     * be replaced if the requested buffer usage or geometry differs from that
     * of the buffer allocated to a slot.
     */
    EglSlot mEglSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];

    /**
     * protects static initialization
     */
    static Mutex sStaticInitLock;

    /**
     * mReleasedTexImageBuffer is a dummy buffer used when in single buffer
     * mode and releaseTexImage() has been called
     */
    static sp<GraphicBuffer> sReleasedTexImageBuffer;
    sp<EglImage> mReleasedTexImage;
};

} // namespace android
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <cutils/compiler.h>
#include <gui/BufferItem.h>
#include <gui/BufferQueueDefs.h>
#include <sys/cdefs.h>
#include <system/graphics.h>

namespace android {

class SurfaceTexture;
class DequeueBufferCallbacks;

/*
 * ImageConsumer implements the parts of SurfaceTexture that deal with
 * images consumed by HWUI view system.
 */
class ImageConsumer {
public:
    typedef status_t (*SurfaceTexture_createReleaseFence)(bool useFenceSync, EGLSyncKHR* eglFence,
                                                          EGLDisplay* display, int* releaseFence,
                                                          void* fencePassThroughHandle);

    typedef status_t (*SurfaceTexture_fenceWait)(int fence, void* fencePassThroughHandle);

    sp<GraphicBuffer> dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
                                    bool* outQueueEmpty, SurfaceTexture& cb,
                                    SurfaceTexture_createReleaseFence createFence,
                                    SurfaceTexture_fenceWait fenceWait,
                                    void* fencePassThroughHandle);

    /**
     * onReleaseBufferLocked amends the ConsumerBase method to update the
     * mImageSlots array in addition to the ConsumerBase.
     */
    void onReleaseBufferLocked(int slot);

private:
    /**
     * ImageSlot contains the information and object references that
     * ImageConsumer maintains about a BufferQueue buffer slot.
     */
    class ImageSlot {
    public:
        ImageSlot() : mEglFence(EGL_NO_SYNC_KHR) {}

        inline EGLSyncKHR& eglFence() { return mEglFence; }

    private:
        /**
         * mEglFence is the EGL sync object that must signal before the buffer
         * associated with this buffer slot may be dequeued.
         */
        EGLSyncKHR mEglFence;
    };

    /**
     * ImageConsumer stores the SkImages that have been allocated by the BufferQueue
     * for each buffer slot.  It is initialized to null pointers, and gets
     * filled in with the result of BufferQueue::acquire when the
     * client dequeues a buffer from a
     * slot that has not yet been used. The buffer allocated to a slot will also
     * be replaced if the requested buffer usage or geometry differs from that
     * of the buffer allocated to a slot.
     */
    ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
};

} /* namespace android */
+472 −0

File added.

Preview size limit exceeded, changes collapsed.

+91 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H
#define _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <system/graphics.h>

#include <gui/IGraphicBufferProducer.h>
#include <gui/surfacetexture/SurfaceTexture.h>

// This file provides a facade API on top of SurfaceTexture, which avoids using
// C++ types. This is still a C++ unstable API though. Ideally features here
// will be exposed via public NDK API and this file will be deleted.

struct ASurfaceTexture {
    android::sp<android::SurfaceTexture> consumer;
    android::sp<android::IGraphicBufferProducer> producer;
};

namespace android {

/**
 * ASurfaceTexture_getCurrentTextureTarget returns the texture target of the
 * current texture.
 */
unsigned int ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture* st);

/**
 * ASurfaceTexture_takeConsumerOwnership attaches an ASurfaceTexture that is
 * currently in the 'detached' state to a consumer context.
 */
void ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture* st);

/**
 * ASurfaceTexture_releaseConsumerOwnership detaches a SurfaceTexture from
 * a consumer context.
 */
void ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture* st);

/**
 * Callback function needed by ASurfaceTexture_dequeueBuffer. It creates a
 * fence that is signalled when the previous buffer is no longer in use by the
 * consumer (usually HWUI RenderThread) and can be written to by the producer.
 */
typedef int (*ASurfaceTexture_createReleaseFence)(bool useFenceSync, EGLSyncKHR* eglFence,
                                                  EGLDisplay* display, int* releaseFence,
                                                  void* fencePassThroughHandle);

/**
 * Callback function needed by ASurfaceTexture_dequeueBuffer. It waits for the
 * new buffer fence to signal before issuing any draw commands.
 */
typedef int (*ASurfaceTexture_fenceWait)(int fence, void* fencePassThroughHandle);

/**
 * ASurfaceTexture_dequeueBuffer returns the next available AHardwareBuffer.
 */
AHardwareBuffer* ASurfaceTexture_dequeueBuffer(ASurfaceTexture* st, int* outSlotid,
                                               android_dataspace* outDataspace,
                                               float* outTransformMatrix, bool* outNewContent,
                                               ASurfaceTexture_createReleaseFence createFence,
                                               ASurfaceTexture_fenceWait fenceWait,
                                               void* fencePassThroughHandle);

/**
 * ASurfaceTexture_create creates an ASurfaceTexture, which is
 * a simple struct containing a SurfaceTexture and an IGraphicBufferProducer.
 */
ASurfaceTexture* ASurfaceTexture_create(sp<SurfaceTexture> consumer,
                                        sp<IGraphicBufferProducer> producer);

} // namespace android

#endif // _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H
Loading