1441e847feb0e055ecb004802802cea07782ab228Andy McFadden/*
2441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Copyright 2013 The Android Open Source Project
3441e847feb0e055ecb004802802cea07782ab228Andy McFadden *
4441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
5441e847feb0e055ecb004802802cea07782ab228Andy McFadden * you may not use this file except in compliance with the License.
6441e847feb0e055ecb004802802cea07782ab228Andy McFadden * You may obtain a copy of the License at
7441e847feb0e055ecb004802802cea07782ab228Andy McFadden *
8441e847feb0e055ecb004802802cea07782ab228Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
9441e847feb0e055ecb004802802cea07782ab228Andy McFadden *
10441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Unless required by applicable law or agreed to in writing, software
11441e847feb0e055ecb004802802cea07782ab228Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
12441e847feb0e055ecb004802802cea07782ab228Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13441e847feb0e055ecb004802802cea07782ab228Andy McFadden * See the License for the specific language governing permissions and
14441e847feb0e055ecb004802802cea07782ab228Andy McFadden * limitations under the License.
15441e847feb0e055ecb004802802cea07782ab228Andy McFadden */
16441e847feb0e055ecb004802802cea07782ab228Andy McFadden
17441e847feb0e055ecb004802802cea07782ab228Andy McFadden#ifndef SCREENRECORD_OVERLAY_H
18441e847feb0e055ecb004802802cea07782ab228Andy McFadden#define SCREENRECORD_OVERLAY_H
19441e847feb0e055ecb004802802cea07782ab228Andy McFadden
20441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "Program.h"
21441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "TextRenderer.h"
22441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "EglWindow.h"
23441e847feb0e055ecb004802802cea07782ab228Andy McFadden
24441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <gui/BufferQueue.h>
25441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <gui/GLConsumer.h>
26441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <utils/Thread.h>
27441e847feb0e055ecb004802802cea07782ab228Andy McFadden
28441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <EGL/egl.h>
29441e847feb0e055ecb004802802cea07782ab228Andy McFadden
30441e847feb0e055ecb004802802cea07782ab228Andy McFaddennamespace android {
31441e847feb0e055ecb004802802cea07782ab228Andy McFadden
32441e847feb0e055ecb004802802cea07782ab228Andy McFadden/*
33441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Overlay "filter".  This sits between the virtual display and the video
34441e847feb0e055ecb004802802cea07782ab228Andy McFadden * encoder.
35441e847feb0e055ecb004802802cea07782ab228Andy McFadden *
36441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Most functions run on a thread created by start().
37441e847feb0e055ecb004802802cea07782ab228Andy McFadden */
38441e847feb0e055ecb004802802cea07782ab228Andy McFaddenclass Overlay : public GLConsumer::FrameAvailableListener, Thread {
39441e847feb0e055ecb004802802cea07782ab228Andy McFaddenpublic:
40545bcd53c828cf5b57e9158feb2e24bf0cd77985Pablo Ceballos    Overlay(bool monotonicTimestamps) : Thread(false),
41441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mThreadResult(UNKNOWN_ERROR),
42441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mState(UNINITIALIZED),
43441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mFrameAvailable(false),
44441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mExtTextureName(0),
45441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mStartMonotonicNsecs(0),
46441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mStartRealtimeNsecs(0),
47441e847feb0e055ecb004802802cea07782ab228Andy McFadden        mLastFrameNumber(-1),
48545bcd53c828cf5b57e9158feb2e24bf0cd77985Pablo Ceballos        mTotalDroppedFrames(0),
49545bcd53c828cf5b57e9158feb2e24bf0cd77985Pablo Ceballos        mUseMonotonicTimestamps(monotonicTimestamps)
50441e847feb0e055ecb004802802cea07782ab228Andy McFadden        {}
51441e847feb0e055ecb004802802cea07782ab228Andy McFadden
52441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Creates a thread that performs the overlay.  Pass in the surface that
53441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // output will be sent to.
54441e847feb0e055ecb004802802cea07782ab228Andy McFadden    //
55441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // This creates a dedicated thread for processing frames.
56441e847feb0e055ecb004802802cea07782ab228Andy McFadden    //
57441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Returns a reference to the producer side of a new BufferQueue that will
58441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // be used by the virtual display.
59441e847feb0e055ecb004802802cea07782ab228Andy McFadden    status_t start(const sp<IGraphicBufferProducer>& outputSurface,
60441e847feb0e055ecb004802802cea07782ab228Andy McFadden            sp<IGraphicBufferProducer>* pBufferProducer);
61441e847feb0e055ecb004802802cea07782ab228Andy McFadden
62441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Stops the thread and releases resources.  It's okay to call this even
63441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // if start() was never called.
64441e847feb0e055ecb004802802cea07782ab228Andy McFadden    status_t stop();
65441e847feb0e055ecb004802802cea07782ab228Andy McFadden
66441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // This creates an EGL context and window surface, draws some informative
67441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // text on it, swaps the buffer, and then tears the whole thing down.
68441e847feb0e055ecb004802802cea07782ab228Andy McFadden    static status_t drawInfoPage(const sp<IGraphicBufferProducer>& outputSurface);
69441e847feb0e055ecb004802802cea07782ab228Andy McFadden
70441e847feb0e055ecb004802802cea07782ab228Andy McFaddenprivate:
71441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Overlay(const Overlay&);
72441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Overlay& operator=(const Overlay&);
73441e847feb0e055ecb004802802cea07782ab228Andy McFadden
74778dccf9a7aa05e0c8df1481ea1d6048bb659667Andy McFadden    // Destruction via RefBase.
75778dccf9a7aa05e0c8df1481ea1d6048bb659667Andy McFadden    virtual ~Overlay() { assert(mState == UNINITIALIZED || mState == STOPPED); }
76778dccf9a7aa05e0c8df1481ea1d6048bb659667Andy McFadden
77441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Draw the initial info screen.
78441e847feb0e055ecb004802802cea07782ab228Andy McFadden    static void doDrawInfoPage(const EglWindow& window,
79441e847feb0e055ecb004802802cea07782ab228Andy McFadden            const Program& texRender, TextRenderer& textRenderer);
80441e847feb0e055ecb004802802cea07782ab228Andy McFadden
81441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // (overrides GLConsumer::FrameAvailableListener method)
8204f101c35eaa90b1f95939afac30674ec1611e6fDan Stoza    virtual void onFrameAvailable(const BufferItem& item);
83441e847feb0e055ecb004802802cea07782ab228Andy McFadden
84441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // (overrides Thread method)
85441e847feb0e055ecb004802802cea07782ab228Andy McFadden    virtual bool threadLoop();
86441e847feb0e055ecb004802802cea07782ab228Andy McFadden
87441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // One-time setup (essentially object construction on the overlay thread).
88441e847feb0e055ecb004802802cea07782ab228Andy McFadden    status_t setup_l();
89441e847feb0e055ecb004802802cea07782ab228Andy McFadden
90441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Release all resources held.
91441e847feb0e055ecb004802802cea07782ab228Andy McFadden    void release_l();
92441e847feb0e055ecb004802802cea07782ab228Andy McFadden
93441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Release EGL display, context, surface.
94441e847feb0e055ecb004802802cea07782ab228Andy McFadden    void eglRelease_l();
95441e847feb0e055ecb004802802cea07782ab228Andy McFadden
96441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Process a frame received from the virtual display.
97441e847feb0e055ecb004802802cea07782ab228Andy McFadden    void processFrame_l();
98441e847feb0e055ecb004802802cea07782ab228Andy McFadden
99441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Convert a monotonic time stamp into a string with the current time.
100441e847feb0e055ecb004802802cea07782ab228Andy McFadden    void getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen);
101441e847feb0e055ecb004802802cea07782ab228Andy McFadden
102441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Guards all fields below.
103441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Mutex mMutex;
104441e847feb0e055ecb004802802cea07782ab228Andy McFadden
105441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Initialization gate.
106441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Condition mStartCond;
107441e847feb0e055ecb004802802cea07782ab228Andy McFadden
108441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Thread status, mostly useful during startup.
109441e847feb0e055ecb004802802cea07782ab228Andy McFadden    status_t mThreadResult;
110441e847feb0e055ecb004802802cea07782ab228Andy McFadden
111441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Overlay thread state.  States advance from left to right; object may
112441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // not be restarted.
113441e847feb0e055ecb004802802cea07782ab228Andy McFadden    enum { UNINITIALIZED, INIT, RUNNING, STOPPING, STOPPED } mState;
114441e847feb0e055ecb004802802cea07782ab228Andy McFadden
115441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Event notification.  Overlay thread sleeps on this until a frame
116441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // arrives or it's time to shut down.
117441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Condition mEventCond;
118441e847feb0e055ecb004802802cea07782ab228Andy McFadden
119441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Set by the FrameAvailableListener callback.
120441e847feb0e055ecb004802802cea07782ab228Andy McFadden    bool mFrameAvailable;
121441e847feb0e055ecb004802802cea07782ab228Andy McFadden
122441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // The surface we send our output to, i.e. the video encoder's input
123441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // surface.
124441e847feb0e055ecb004802802cea07782ab228Andy McFadden    sp<IGraphicBufferProducer> mOutputSurface;
125441e847feb0e055ecb004802802cea07782ab228Andy McFadden
126b278f5e70c001391779525fb4d3b024503ba9466Dan Stoza    // Producer side of queue, passed into the virtual display.
127b278f5e70c001391779525fb4d3b024503ba9466Dan Stoza    // The consumer end feeds into our GLConsumer.
128b278f5e70c001391779525fb4d3b024503ba9466Dan Stoza    sp<IGraphicBufferProducer> mProducer;
129441e847feb0e055ecb004802802cea07782ab228Andy McFadden
130441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // This receives frames from the virtual display and makes them available
131441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // as an external texture.
132441e847feb0e055ecb004802802cea07782ab228Andy McFadden    sp<GLConsumer> mGlConsumer;
133441e847feb0e055ecb004802802cea07782ab228Andy McFadden
134441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // EGL display / context / surface.
135441e847feb0e055ecb004802802cea07782ab228Andy McFadden    EglWindow mEglWindow;
136441e847feb0e055ecb004802802cea07782ab228Andy McFadden
137441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // GL rendering support.
138441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Program mExtTexProgram;
139441e847feb0e055ecb004802802cea07782ab228Andy McFadden    Program mTexProgram;
140441e847feb0e055ecb004802802cea07782ab228Andy McFadden
141441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Text rendering.
142441e847feb0e055ecb004802802cea07782ab228Andy McFadden    TextRenderer mTextRenderer;
143441e847feb0e055ecb004802802cea07782ab228Andy McFadden
144441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // External texture, updated by GLConsumer.
145441e847feb0e055ecb004802802cea07782ab228Andy McFadden    GLuint mExtTextureName;
146441e847feb0e055ecb004802802cea07782ab228Andy McFadden
147441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Start time, used to map monotonic to wall-clock time.
148441e847feb0e055ecb004802802cea07782ab228Andy McFadden    nsecs_t mStartMonotonicNsecs;
149441e847feb0e055ecb004802802cea07782ab228Andy McFadden    nsecs_t mStartRealtimeNsecs;
150441e847feb0e055ecb004802802cea07782ab228Andy McFadden
151441e847feb0e055ecb004802802cea07782ab228Andy McFadden    // Used for tracking dropped frames.
152441e847feb0e055ecb004802802cea07782ab228Andy McFadden    nsecs_t mLastFrameNumber;
153441e847feb0e055ecb004802802cea07782ab228Andy McFadden    size_t mTotalDroppedFrames;
154441e847feb0e055ecb004802802cea07782ab228Andy McFadden
155545bcd53c828cf5b57e9158feb2e24bf0cd77985Pablo Ceballos    bool mUseMonotonicTimestamps;
156545bcd53c828cf5b57e9158feb2e24bf0cd77985Pablo Ceballos
157441e847feb0e055ecb004802802cea07782ab228Andy McFadden    static const char* kPropertyNames[];
158441e847feb0e055ecb004802802cea07782ab228Andy McFadden};
159441e847feb0e055ecb004802802cea07782ab228Andy McFadden
160441e847feb0e055ecb004802802cea07782ab228Andy McFadden}; // namespace android
161441e847feb0e055ecb004802802cea07782ab228Andy McFadden
162441e847feb0e055ecb004802802cea07782ab228Andy McFadden#endif /*SCREENRECORD_OVERLAY_H*/
163