cleanups in preparation of bigger changes

- fix typo drawForSreenshot misspelled
- get rid of DisplayDeviceBase
- removed unused or unneeded code
- always pass a DisplayDevice to Layer methods that are called
  on a per-display basis (to make it clear that this could be
  called more than once per composition).

Change-Id: Id948b7e09fe5c06db0e42d40d6ed75dd095c7f44
This commit is contained in:
Mathias Agopian 2012-08-02 14:01:42 -07:00
parent 0f2f5ff75b
commit d3ee231edd
14 changed files with 151 additions and 186 deletions

View File

@ -9,7 +9,6 @@ LOCAL_SRC_FILES:= \
LayerBase.cpp \
LayerDim.cpp \
LayerScreenshot.cpp \
DisplayHardware/DisplayDeviceBase.cpp \
DisplayHardware/FramebufferSurface.cpp \
DisplayHardware/HWComposer.cpp \
DisplayHardware/PowerHAL.cpp \

View File

@ -34,7 +34,6 @@
#include <hardware/gralloc.h>
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/DisplayDeviceBase.h"
#include "DisplayHardware/HWComposer.h"
#include "DisplayDevice.h"
@ -103,13 +102,23 @@ DisplayDevice::DisplayDevice(
int display,
const sp<SurfaceTextureClient>& surface,
EGLConfig config)
: DisplayDeviceBase(display),
mFlinger(flinger),
mDisplayId(display),
mNativeWindow(surface),
mFlags(0),
mSecureLayerVisible(false),
mLayerStack(0)
: mFlinger(flinger),
mDisplayId(display),
mNativeWindow(surface),
mDisplay(EGL_NO_DISPLAY),
mSurface(EGL_NO_SURFACE),
mContext(EGL_NO_CONTEXT),
mDpiX(), mDpiY(),
mRefreshRate(),
mDensity(),
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
mRefreshPeriod(),
mSecureLayerVisible(false),
mScreenAcquired(false),
mOrientation(),
mLayerStack(0)
{
init(config);
}
@ -248,15 +257,6 @@ uint32_t DisplayDevice::getPageFlipCount() const {
return mPageFlipCount;
}
nsecs_t DisplayDevice::getRefreshTimestamp() const {
// this returns the last refresh timestamp.
// if the last one is not available, we estimate it based on
// the refresh period and whatever closest timestamp we have.
Mutex::Autolock _l(mLock);
nsecs_t now = systemTime(CLOCK_MONOTONIC);
return now - ((now - mLastHwVSync) % mRefreshPeriod);
}
nsecs_t DisplayDevice::getRefreshPeriod() const {
return mRefreshPeriod;
}
@ -268,11 +268,6 @@ status_t DisplayDevice::compositionComplete() const {
return mFramebufferSurface->compositionComplete();
}
void DisplayDevice::onVSyncReceived(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mLastHwVSync = timestamp;
}
void DisplayDevice::flip(const Region& dirty) const
{
checkGLErrors();
@ -340,6 +335,24 @@ bool DisplayDevice::getSecureLayerVisible() const {
// ----------------------------------------------------------------------------
bool DisplayDevice::canDraw() const {
return mScreenAcquired;
}
void DisplayDevice::releaseScreen() const {
mScreenAcquired = false;
}
void DisplayDevice::acquireScreen() const {
mScreenAcquired = true;
}
bool DisplayDevice::isScreenAcquired() const {
return mScreenAcquired;
}
// ----------------------------------------------------------------------------
status_t DisplayDevice::orientationToTransfrom(
int orientation, int w, int h, Transform* tr)
{

View File

@ -14,16 +14,14 @@
* limitations under the License.
*/
#ifndef ANDROID_DISPLAY_HARDWARE_H
#define ANDROID_DISPLAY_HARDWARE_H
#ifndef ANDROID_DISPLAY_DEVICE_H
#define ANDROID_DISPLAY_DEVICE_H
#include <stdlib.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@ -32,8 +30,6 @@
#include "Transform.h"
#include "DisplayHardware/DisplayDeviceBase.h"
namespace android {
class DisplayInfo;
@ -42,7 +38,7 @@ class LayerBase;
class SurfaceFlinger;
class SurfaceTextureClient;
class DisplayDevice : public DisplayDeviceBase
class DisplayDevice
{
public:
// region in layer-stack space
@ -63,14 +59,12 @@ public:
const sp<SurfaceTextureClient>& surface,
EGLConfig config);
virtual ~DisplayDevice();
~DisplayDevice();
// Flip the front and back buffers if the back buffer is "dirty". Might
// be instantaneous, might involve copying the frame buffer around.
void flip(const Region& dirty) const;
void onVSyncReceived(nsecs_t timestamp);
float getDpiX() const;
float getDpiY() const;
float getRefreshRate() const;
@ -80,7 +74,6 @@ public:
PixelFormat getFormat() const;
uint32_t getFlags() const;
nsecs_t getRefreshPeriod() const;
nsecs_t getRefreshTimestamp() const;
status_t getInfo(DisplayInfo* info) const;
EGLSurface getEGLSurface() const;
@ -94,12 +87,6 @@ public:
const Transform& getTransform() const { return mGlobalTransform; }
uint32_t getLayerStack() const { return mLayerStack; }
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
void dump(String8& res) const;
status_t compositionComplete() const;
Rect getBounds() const {
@ -109,6 +96,21 @@ public:
static void makeCurrent(const DisplayDevice& hw, EGLContext ctx);
/* ------------------------------------------------------------------------
* blank / unplank management
*/
void releaseScreen() const;
void acquireScreen() const;
bool isScreenAcquired() const;
bool canDraw() const;
/* ------------------------------------------------------------------------
* Debugging
*/
uint32_t getPageFlipCount() const;
void dump(String8& res) const;
private:
void init(EGLConfig config);
@ -117,12 +119,13 @@ private:
*/
sp<SurfaceFlinger> mFlinger;
int mDisplayId;
// ANativeWindow this display is rendering into
sp<SurfaceTextureClient> mNativeWindow;
// set if mNativeWindow is a FramebufferSurface
sp<FramebufferSurface> mFramebufferSurface;
EGLDisplay mDisplay;
EGLSurface mSurface;
EGLContext mContext;
@ -135,35 +138,33 @@ private:
PixelFormat mFormat;
uint32_t mFlags;
mutable uint32_t mPageFlipCount;
nsecs_t mRefreshPeriod;
/*
* Can only accessed from the main thread, these members
* don't need synchronization.
*/
// list of visible layers on that display
Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
// Whether we have a visible secure layer on this display
bool mSecureLayerVisible;
// Whether the screen is blanked;
mutable int mScreenAcquired;
// this used to be in GraphicPlane
/*
* Transaction state
*/
static status_t orientationToTransfrom(int orientation, int w, int h,
Transform* tr);
Transform mGlobalTransform;
int mOrientation;
uint32_t mLayerStack;
/*
* protected by mLock
*/
mutable Mutex mLock;
mutable nsecs_t mLastHwVSync;
};
}; // namespace android
#endif // ANDROID_DISPLAY_HARDWARE_H
#endif // ANDROID_DISPLAY_DEVICE_H

View File

@ -1,48 +0,0 @@
/*
* Copyright (C) 2012 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.
*/
#include <stdint.h>
#include <sys/types.h>
#include "DisplayHardware/DisplayDeviceBase.h"
// ----------------------------------------------------------------------------
namespace android {
DisplayDeviceBase::DisplayDeviceBase(uint32_t displayIndex) {
mScreenAcquired = true;
}
DisplayDeviceBase::~DisplayDeviceBase() {
}
bool DisplayDeviceBase::canDraw() const {
return mScreenAcquired;
}
void DisplayDeviceBase::releaseScreen() const {
mScreenAcquired = false;
}
void DisplayDeviceBase::acquireScreen() const {
mScreenAcquired = true;
}
bool DisplayDeviceBase::isScreenAcquired() const {
return mScreenAcquired;
}
}; // namespace android

View File

@ -1,42 +0,0 @@
/*
* Copyright (C) 2012 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_DISPLAY_HARDWARE_BASE_H
#define ANDROID_DISPLAY_HARDWARE_BASE_H
#include <stdint.h>
namespace android {
class DisplayDeviceBase {
public:
DisplayDeviceBase(uint32_t displayIndex);
~DisplayDeviceBase();
// console management
void releaseScreen() const;
void acquireScreen() const;
bool isScreenAcquired() const;
bool canDraw() const;
private:
mutable int mScreenAcquired;
};
}; // namespace android
#endif // ANDROID_DISPLAY_HARDWARE_BASE_H

View File

@ -185,6 +185,17 @@ void HWComposer::invalidate() {
void HWComposer::vsync(int dpy, int64_t timestamp) {
ATRACE_INT("VSYNC", ++mVSyncCount&1);
mEventHandler.onVSyncReceived(dpy, timestamp);
Mutex::Autolock _l(mLock);
mLastHwVSync = timestamp;
}
nsecs_t HWComposer::getRefreshTimestamp() const {
// this returns the last refresh timestamp.
// if the last one is not available, we estimate it based on
// the refresh period and whatever closest timestamp we have.
Mutex::Autolock _l(mLock);
nsecs_t now = systemTime(CLOCK_MONOTONIC);
return now - ((now - mLastHwVSync) % mRefreshPeriod);
}
void HWComposer::eventControl(int event, int enabled) {

View File

@ -189,6 +189,8 @@ public:
void eventControl(int event, int enabled);
nsecs_t getRefreshTimestamp() const;
// this class is only used to fake the VSync event on systems that don't
// have it.
class VSyncThread : public Thread {
@ -235,6 +237,10 @@ private:
size_t mVSyncCount;
sp<VSyncThread> mVSyncThread;
bool mDebugForceFakeVSync;
// protected by mLock
mutable Mutex mLock;
mutable nsecs_t mLastHwVSync;
};
// ---------------------------------------------------------------------------

View File

@ -60,7 +60,6 @@ Layer::Layer(SurfaceFlinger* flinger,
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
mNeedHwcFence(false),
mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
@ -72,21 +71,11 @@ Layer::Layer(SurfaceFlinger* flinger,
glGenTextures(1, &mTextureName);
}
void Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) {
void Layer::onLayerDisplayed(const DisplayDevice& hw,
HWComposer::HWCLayerInterface* layer) {
if (layer) {
mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
}
if (mFrameLatencyNeeded) {
// we need a DisplayDevice for debugging only right now
// XXX: should this be called per DisplayDevice?
const DisplayDevice& hw(mFlinger->getDefaultDisplayDevice());
mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
mFrameStats[mFrameLatencyOffset].set = systemTime();
mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
mFrameLatencyNeeded = false;
}
}
void Layer::onFirstRef()
@ -285,16 +274,22 @@ void Layer::setGeometry(
layer.setCrop(computeBufferCrop());
}
void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
void Layer::setPerFrameData(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer) {
const sp<GraphicBuffer>& buffer(mActiveBuffer);
// NOTE: buffer can be NULL if the client never drew into this
// layer yet, or if we ran out of memory
layer.setBuffer(buffer);
}
void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
void Layer::setAcquireFence(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer) {
int fenceFd = -1;
if (mNeedHwcFence && (layer.getCompositionType() == HWC_OVERLAY)) {
// TODO: there is a possible optimization here: we only need to set the
// acquire fence the first time a new buffer is acquired on EACH display.
if (layer.getCompositionType() == HWC_OVERLAY) {
sp<Fence> fence = mSurfaceTexture->getCurrentFence();
if (fence.get()) {
fenceFd = fence->dup();
@ -302,7 +297,6 @@ void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
ALOGW("failed to dup layer fence, skipping sync: %d", errno);
}
}
mNeedHwcFence = false;
}
layer.setAcquireFenceFd(fenceFd);
}
@ -517,6 +511,18 @@ bool Layer::onPreComposition() {
return mQueuedFrames > 0;
}
void Layer::onPostComposition() {
if (mFrameLatencyNeeded) {
const HWComposer& hwc = mFlinger->getHwComposer();
const size_t offset = mFrameLatencyOffset;
mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
mFrameStats[offset].set = systemTime();
mFrameStats[offset].vsync = hwc.getRefreshTimestamp();
mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
mFrameLatencyNeeded = false;
}
}
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
ATRACE_CALL();
@ -646,7 +652,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
mRefreshPending = true;
mFrameLatencyNeeded = true;
mNeedHwcFence = true;
if (oldActiveBuffer == NULL) {
// the first time we receive a buffer, we need to trigger a
// geometry invalidation.

View File

@ -66,8 +66,14 @@ public:
// LayerBase interface
virtual void setGeometry(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
virtual void onLayerDisplayed(const DisplayDevice& hw,
HWComposer::HWCLayerInterface* layer);
virtual bool onPreComposition();
virtual void onPostComposition();
virtual void onDraw(const DisplayDevice& hw, const Region& clip) const;
virtual uint32_t doTransaction(uint32_t transactionFlags);
@ -82,9 +88,6 @@ public:
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;
virtual void onLayerDisplayed(HWComposer::HWCLayerInterface* layer);
virtual bool onPreComposition();
// only for debugging
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
@ -121,7 +124,6 @@ private:
bool mCurrentOpacity;
bool mRefreshPending;
bool mFrameLatencyNeeded;
bool mNeedHwcFence;
int mFrameLatencyOffset;
struct Statistics {

View File

@ -291,11 +291,13 @@ void LayerBase::setGeometry(
layer.setVisibleRegionScreen(tr.transform(visibleRegion));
}
void LayerBase::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
void LayerBase::setPerFrameData(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer) {
layer.setBuffer(0);
}
void LayerBase::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
void LayerBase::setAcquireFence(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer) {
layer.setAcquireFenceFd(-1);
}
@ -314,7 +316,7 @@ void LayerBase::draw(const DisplayDevice& hw, const Region& clip) const
onDraw(hw, clip);
}
void LayerBase::drawForSreenShot(const DisplayDevice& hw)
void LayerBase::drawForScreenShot(const DisplayDevice& hw)
{
setFiltering(true);
onDraw( hw, Region(hw.bounds()) );

View File

@ -134,8 +134,10 @@ public:
virtual void setGeometry(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(const DisplayDevice& hw,
HWComposer::HWCLayerInterface& layer);
/**
* draw - performs some global clipping optimizations
@ -144,7 +146,7 @@ public:
* to perform the actual drawing.
*/
virtual void draw(const DisplayDevice& hw, const Region& clip) const;
virtual void drawForSreenShot(const DisplayDevice& hw);
virtual void drawForScreenShot(const DisplayDevice& hw);
/**
* onDraw - draws the surface.
@ -216,13 +218,18 @@ public:
/** called after page-flip
*/
virtual void onLayerDisplayed(HWComposer::HWCLayerInterface* layer) { }
virtual void onLayerDisplayed(const DisplayDevice& hw,
HWComposer::HWCLayerInterface* layer) { }
/** called before composition.
* returns true if the layer has pending updates.
*/
virtual bool onPreComposition() { return false; }
/** called before composition.
*/
virtual void onPostComposition() { }
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
virtual void shortDump(String8& result, char* scratch, size_t size) const;

View File

@ -18,6 +18,9 @@
#include <stdint.h>
#include <sys/types.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <utils/Errors.h>
#include <utils/Log.h>

View File

@ -18,6 +18,9 @@
#include <stdint.h>
#include <sys/types.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <utils/Errors.h>
#include <utils/Log.h>

View File

@ -475,7 +475,7 @@ void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
if (display != NULL) {
stc = new SurfaceTextureClient(display);
result = eglCreateWindowSurface(hw.getEGLDisplay(),
result = eglCreateWindowSurface(mEGLDisplay,
mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
ALOGE_IF(result == EGL_NO_SURFACE,
"eglCreateWindowSurface failed (ISurfaceTexture=%p)",
@ -493,7 +493,7 @@ void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
if (old_surface != EGL_NO_SURFACE) {
// Note: EGL allows to destroy an object while its current
// it will fail to become current next time though.
eglDestroySurface(hw.getEGLDisplay(), old_surface);
eglDestroySurface(mEGLDisplay, old_surface);
}
}
@ -540,8 +540,6 @@ bool SurfaceFlinger::threadLoop() {
}
void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
DisplayDevice& hw(const_cast<DisplayDevice&>(getDisplayDevice(dpy)));
hw.onVSyncReceived(timestamp);
mEventThread->onVSyncReceived(dpy, timestamp);
}
@ -640,7 +638,7 @@ void SurfaceFlinger::handleMessageRefresh() {
* update the per-frame h/w composer data for each layer
* and build the transparent region of the FB
*/
layer->setPerFrameData(*cur);
layer->setPerFrameData(hw, *cur);
}
}
status_t err = hwc.prepare();
@ -700,7 +698,7 @@ void SurfaceFlinger::handleMessageRefresh() {
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
layer->drawForSreenShot(hw);
layer->drawForScreenShot(hw);
}
success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
@ -736,7 +734,7 @@ void SurfaceFlinger::postFramebuffer()
const HWComposer::LayerListIterator end = hwc.end();
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(currentLayers[i]);
layer->setAcquireFence(*cur);
layer->setAcquireFence(hw, *cur);
}
}
hw.flip(hw.swapRegion);
@ -756,12 +754,12 @@ void SurfaceFlinger::postFramebuffer()
HWComposer::LayerListIterator cur = hwc.begin();
const HWComposer::LayerListIterator end = hwc.end();
for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
currentLayers[i]->onLayerDisplayed(&*cur);
currentLayers[i]->onLayerDisplayed(hw, &*cur);
}
} else {
eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
for (size_t i = 0; i < count; i++) {
currentLayers[i]->onLayerDisplayed(NULL);
currentLayers[i]->onLayerDisplayed(hw, NULL);
}
}
@ -1096,6 +1094,12 @@ void SurfaceFlinger::handleRepaint(const DisplayDevice& hw,
composeSurfaces(hw, dirtyRegion);
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
currentLayers[i]->onPostComposition();
}
// update the swap region and clear the dirty region
hw.swapRegion.orSelf(dirtyRegion);
}
@ -1791,8 +1795,7 @@ void SurfaceFlinger::dumpAllLocked(
result.append(buffer);
snprintf(buffer, SIZE, "EGL : %s\n",
eglQueryString(hw.getEGLDisplay(),
EGL_VERSION_HW_ANDROID));
eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
result.append(buffer);
snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
@ -2023,7 +2026,7 @@ status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
layer->drawForSreenShot(hw);
layer->drawForScreenShot(hw);
}
hw.compositionComplete();
@ -2583,7 +2586,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
if (!(flags & ISurfaceComposer::eLayerHidden)) {
const uint32_t z = layer->drawingState().z;
if (z >= minLayerZ && z <= maxLayerZ) {
layer->drawForSreenShot(hw);
layer->drawForScreenShot(hw);
}
}
}