*/
#define DEBUG_SCREENSHOTS false
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
namespace android {
// ---------------------------------------------------------------------------
void SurfaceFlinger::bootFinished()
{
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
sp<VSyncSource::Callback> mCallback;
};
+// Do not call property_set on main thread which will be blocked by init
+// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
- mHwc = new HWComposer(this,
- *static_cast<HWComposer::EventHandler *>(this));
+ mHwc.reset(new HWComposer(this,
+ *static_cast<HWComposer::EventHandler *>(this)));
// get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay,
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
- // Inform native graphics APIs that the present timestamp is NOT supported:
- property_set(kTimestampProperty, "0");
-
// initialize our non-virtual displays
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
mRenderEngine->primeCache();
- mStartBootAnimThread = new StartBootAnimThread();
- if (mStartBootAnimThread->Start() != NO_ERROR) {
- ALOGE("Run StartBootAnimThread failed!");
+ // Inform native graphics APIs that the present timestamp is NOT supported:
+ mStartPropertySetThread = new StartPropertySetThread(false);
+ if (mStartPropertySetThread->Start() != NO_ERROR) {
+ ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
void SurfaceFlinger::startBootAnim() {
// Start boot animation service by setting a property mailbox
// if property setting thread is already running, Start() will be just a NOP
- mStartBootAnimThread->Start();
+ mStartPropertySetThread->Start();
// Wait until property was set
- if (mStartBootAnimThread->join() != NO_ERROR) {
- ALOGE("Join StartBootAnimThread failed!");
+ if (mStartPropertySetThread->join() != NO_ERROR) {
+ ALOGE("Join StartPropertySetThread failed!");
}
}
const HWComposer& hwc = getHwComposer();
const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ mGlCompositionDoneTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
if (getHwComposer().hasGlesComposition(hw->getHwcDisplayId())) {
glCompositionDoneFenceTime =
} else {
glCompositionDoneFenceTime = FenceTime::NO_FENCE;
}
- mGlCompositionDoneTimeline.updateSignalTimes();
+ mDisplayTimeline.updateSignalTimes();
sp<Fence> retireFence = mHwc->getDisplayFence(HWC_DISPLAY_PRIMARY);
auto retireFenceTime = std::make_shared<FenceTime>(retireFence);
mDisplayTimeline.push(retireFenceTime);
- mDisplayTimeline.updateSignalTimes();
nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
});
if (retireFence->isValid()) {
- if (mPrimaryDispSync.addPresentFence(retireFence)) {
+ if (mPrimaryDispSync.addPresentFence(retireFenceTime)) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
if (hw->isDisplayOn()) {
- computeVisibleRegions(hw->getLayerStack(), dirtyRegion,
- opaqueRegion);
+ computeVisibleRegions(hw, dirtyRegion, opaqueRegion);
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->getLayerStack() == hw->getLayerStack()) {
// TODO: we could cache the transformed region
Region visibleReg;
visibleReg.set(layer->computeScreenBounds());
- invalidateLayerStack(layer->getLayerStack(), visibleReg);
+ invalidateLayerStack(layer, visibleReg);
}
});
}
mTransactionCV.broadcast();
}
-void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
+void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
Region& outDirtyRegion, Region& outOpaqueRegion)
{
ATRACE_CALL();
const Layer::State& s(layer->getDrawingState());
// only consider the layers on the given layer stack
- if (layer->getLayerStack() != layerStack)
+ if (layer->getLayerStack() != displayDevice->getLayerStack())
return;
/*
outOpaqueRegion = aboveOpaqueLayers;
}
-void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
- const Region& dirty) {
+void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
+ uint32_t layerStack = layer->getLayerStack();
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
if (hw->getLayerStack() == layerStack) {
Layer* layer = layersWithQueuedFrames[i];
const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
layer->useSurfaceDamage();
- invalidateLayerStack(layer->getLayerStack(), dirty);
+ invalidateLayerStack(layer, dirty);
}
mVisibleRegionsDirty |= visibleRegions;
return NO_ERROR;
}
+ layer->onRemovedFromCurrentState();
mLayersPendingRemoval.add(layer);
mLayersRemoved = true;
mNumLayers -= 1 + layer->getChildrenCount();