blob: 0a89e5e944f866021c7ba913e6a86ff6e9d02600 [file] [log] [blame]
/*
* Copyright (C) 2013 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 RENDERTHREAD_H_
#define RENDERTHREAD_H_
#include <GrDirectContext.h>
#include <SkBitmap.h>
#include <cutils/compiler.h>
#include <private/android/choreographer.h>
#include <surface_control_private.h>
#include <thread/ThreadBase.h>
#include <utils/Looper.h>
#include <utils/Thread.h>
#include <memory>
#include <mutex>
#include <set>
#include "CacheManager.h"
#include "MemoryPolicy.h"
#include "ProfileDataContainer.h"
#include "RenderTask.h"
#include "TimeLord.h"
#include "WebViewFunctorManager.h"
#include "thread/ThreadBase.h"
#include "utils/TimeUtils.h"
namespace android {
class Bitmap;
namespace uirenderer {
class AutoBackendTextureRelease;
class Readback;
class RenderState;
class TestUtils;
namespace skiapipeline {
class VkFunctorDrawHandler;
}
namespace VectorDrawable {
class Tree;
}
namespace renderthread {
class CanvasContext;
class EglManager;
class RenderProxy;
class VulkanManager;
// Mimics android.view.Choreographer.FrameCallback
class IFrameCallback {
public:
virtual void doFrame() = 0;
protected:
virtual ~IFrameCallback() {}
};
struct VsyncSource {
virtual void requestNextVsync() = 0;
virtual void drainPendingEvents() = 0;
virtual ~VsyncSource() {}
};
typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
typedef void (*ASC_acquire)(ASurfaceControl* control);
typedef void (*ASC_release)(ASurfaceControl* control);
typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, int32_t id,
void* context,
ASurfaceControl_SurfaceStatsListener func);
typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
ASurfaceControl_SurfaceStatsListener func);
typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
typedef ASurfaceTransaction* (*AST_create)();
typedef void (*AST_delete)(ASurfaceTransaction* transaction);
typedef void (*AST_apply)(ASurfaceTransaction* transaction);
typedef void (*AST_reparent)(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
ASurfaceControl* newParentASurfaceControl);
typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
ASurfaceControl* surface_control, int8_t visibility);
typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control,
int32_t z_order);
struct ASurfaceControlFunctions {
ASurfaceControlFunctions();
ASC_create createFunc;
ASC_acquire acquireFunc;
ASC_release releaseFunc;
ASC_registerSurfaceStatsListener registerListenerFunc;
ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
ASCStats_getAcquireTime getAcquireTimeFunc;
ASCStats_getFrameNumber getFrameNumberFunc;
AST_create transactionCreateFunc;
AST_delete transactionDeleteFunc;
AST_apply transactionApplyFunc;
AST_reparent transactionReparentFunc;
AST_setVisibility transactionSetVisibilityFunc;
AST_setZOrder transactionSetZOrderFunc;
};
class ChoreographerSource;
class DummyVsyncSource;
typedef void (*JVMAttachHook)(const char* name);
class RenderThread : private ThreadBase {
PREVENT_COPY_AND_ASSIGN(RenderThread);
public:
// Sets a callback that fires before any RenderThread setup has occurred.
static void setOnStartHook(JVMAttachHook onStartHook);
static JVMAttachHook getOnStartHook();
WorkQueue& queue() { return ThreadBase::queue(); }
// Mimics android.view.Choreographer
void postFrameCallback(IFrameCallback* callback);
bool removeFrameCallback(IFrameCallback* callback);
// If the callback is currently registered, it will be pushed back until
// the next vsync. If it is not currently registered this does nothing.
void pushBackFrameCallback(IFrameCallback* callback);
TimeLord& timeLord() { return mTimeLord; }
RenderState& renderState() const { return *mRenderState; }
EglManager& eglManager() const { return *mEglManager; }
ProfileDataContainer& globalProfileData() { return mGlobalProfileData; }
std::mutex& getJankDataMutex() { return mJankDataMutex; }
Readback& readback();
GrDirectContext* getGrContext() const { return mGrContext.get(); }
void setGrContext(sk_sp<GrDirectContext> cxt);
sk_sp<GrDirectContext> requireGrContext();
CacheManager& cacheManager() { return *mCacheManager; }
VulkanManager& vulkanManager();
sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
void dumpGraphicsMemory(int fd, bool includeProfileData);
void getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage);
void requireGlContext();
void requireVkContext();
void destroyRenderingContext();
void preload();
const ASurfaceControlFunctions& getASurfaceControlFunctions() {
return mASurfaceControlFunctions;
}
void trimMemory(TrimLevel level);
/**
* isCurrent provides a way to query, if the caller is running on
* the render thread.
*
* @return true only if isCurrent is invoked from the render thread.
*/
static bool isCurrent();
static void initGrContextOptions(GrContextOptions& options);
protected:
virtual bool threadLoop() override;
private:
friend class DispatchFrameCallbacks;
friend class RenderProxy;
friend class DummyVsyncSource;
friend class ChoreographerSource;
friend class android::uirenderer::AutoBackendTextureRelease;
friend class android::uirenderer::TestUtils;
friend class android::uirenderer::WebViewFunctor;
friend class android::uirenderer::skiapipeline::VkFunctorDrawHandler;
friend class android::uirenderer::VectorDrawable::Tree;
friend class sp<RenderThread>;
RenderThread();
virtual ~RenderThread();
static bool hasInstance();
static RenderThread& getInstance();
void initThreadLocals();
void initializeChoreographer();
void setupFrameInterval();
// Callbacks for choreographer events:
// choreographerCallback will call AChoreograper_handleEvent to call the
// corresponding callbacks for each display event type
static int choreographerCallback(int fd, int events, void* data);
// Callback that will be run on vsync ticks.
static void extendedFrameCallback(const AChoreographerFrameCallbackData* cbData, void* data);
void frameCallback(int64_t vsyncId, int64_t frameDeadline, int64_t frameTimeNanos,
int64_t frameInterval);
// Callback that will be run whenver there is a refresh rate change.
static void refreshRateCallback(int64_t vsyncPeriod, void* data);
void drainDisplayEventQueue();
void dispatchFrameCallbacks();
void requestVsync();
AChoreographer* mChoreographer;
VsyncSource* mVsyncSource;
bool mVsyncRequested;
std::set<IFrameCallback*> mFrameCallbacks;
// We defer the actual registration of these callbacks until
// both mQueue *and* mDisplayEventReceiver have been drained off all
// immediate events. This makes sure that we catch the next vsync, not
// the previous one
std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks;
bool mFrameCallbackTaskPending;
TimeLord mTimeLord;
nsecs_t mDispatchFrameDelay = 4_ms;
RenderState* mRenderState;
EglManager* mEglManager;
WebViewFunctorManager& mFunctorManager;
ProfileDataContainer mGlobalProfileData;
Readback* mReadback = nullptr;
sk_sp<GrDirectContext> mGrContext;
CacheManager* mCacheManager;
sp<VulkanManager> mVkManager;
ASurfaceControlFunctions mASurfaceControlFunctions;
std::mutex mJankDataMutex;
};
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
#endif /* RENDERTHREAD_H_ */