Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HWComposer : Prevent FB de-allocation with HWC 1.1+ #1

Open
wants to merge 9 commits into
base: 8.0
Choose a base branch
from
2 changes: 2 additions & 0 deletions include/android/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,8 @@ enum {
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
/** rotary encoder */
AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
/** cm gesture sensor */
AINPUT_SOURCE_GESTURE_SENSOR = 0x00800000 | AINPUT_SOURCE_CLASS_NONE,

/** any */
AINPUT_SOURCE_ANY = 0xffffff00,
Expand Down
3 changes: 2 additions & 1 deletion include/gui/ISurfaceComposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ class ISurfaceComposer: public IInterface {
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform,
Rotation rotation = eRotateNone) = 0;
Rotation rotation = eRotateNone,
bool isCpuConsumer = false) = 0;

/* Clears the frame statistics for animations.
*
Expand Down
8 changes: 6 additions & 2 deletions libs/gui/ISurfaceComposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform,
ISurfaceComposer::Rotation rotation)
ISurfaceComposer::Rotation rotation,
bool isCpuConsumer)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
Expand All @@ -118,6 +119,7 @@ class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
data.writeInt32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
data.writeInt32(static_cast<int32_t>(rotation));
data.writeInt32(isCpuConsumer);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
Expand Down Expand Up @@ -550,11 +552,13 @@ status_t BnSurfaceComposer::onTransact(
int32_t maxLayerZ = data.readInt32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
int32_t rotation = data.readInt32();
bool isCpuConsumer = data.readInt32();

status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation));
static_cast<ISurfaceComposer::Rotation>(rotation),
isCpuConsumer);
reply->writeInt32(res);
return NO_ERROR;
}
Expand Down
5 changes: 3 additions & 2 deletions libs/gui/SurfaceComposerClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,8 @@ status_t ScreenshotClient::capture(
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
return s->captureScreen(display, producer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
ISurfaceComposer::eRotateNone, false);
}

status_t ScreenshotClient::captureToBuffer(const sp<IBinder>& display,
Expand Down Expand Up @@ -1013,7 +1014,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,

status_t err = s->captureScreen(display, mProducer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation));
static_cast<ISurfaceComposer::Rotation>(rotation), true);

if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
Expand Down
10 changes: 8 additions & 2 deletions services/inputflinger/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "InputManager.h"

#include <cutils/iosched_policy.h>
#include <log/log.h>

namespace android {
Expand Down Expand Up @@ -51,20 +52,25 @@ void InputManager::initialize() {
}

status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
status_t result = mDispatcherThread->run("InputDispatcher",
PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}

result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
result = mReaderThread->run("InputReader",
PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);

mDispatcherThread->requestExit();
return result;
}

android_set_rt_ioprio(mDispatcherThread->getTid(), 1);
android_set_rt_ioprio(mReaderThread->getTid(), 1);

return OK;
}

Expand Down
8 changes: 8 additions & 0 deletions services/inputflinger/InputReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3247,6 +3247,8 @@ void TouchInputMapper::configureParameters() {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
} else if (deviceTypeString == "pointer") {
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
} else if (deviceTypeString == "gesture") {
mParameters.deviceType = Parameters::DEVICE_TYPE_GESTURE_SENSOR;
} else if (deviceTypeString != "default") {
ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
}
Expand Down Expand Up @@ -3304,6 +3306,9 @@ void TouchInputMapper::dumpParameters(String8& dump) {
case Parameters::DEVICE_TYPE_POINTER:
dump.append(INDENT4 "DeviceType: pointer\n");
break;
case Parameters::DEVICE_TYPE_GESTURE_SENSOR:
dump.append(INDENT4 "DeviceType: gesture\n");
break;
default:
ALOG_ASSERT(false);
}
Expand Down Expand Up @@ -3368,6 +3373,9 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
} else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
mDeviceMode = DEVICE_MODE_NAVIGATION;
} else if (mParameters.deviceType == Parameters::DEVICE_TYPE_GESTURE_SENSOR) {
mSource = AINPUT_SOURCE_GESTURE_SENSOR;
mDeviceMode = DEVICE_MODE_UNSCALED;
} else {
mSource = AINPUT_SOURCE_TOUCHPAD;
mDeviceMode = DEVICE_MODE_UNSCALED;
Expand Down
1 change: 1 addition & 0 deletions services/inputflinger/InputReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,7 @@ class TouchInputMapper : public InputMapper {
DEVICE_TYPE_TOUCH_SCREEN,
DEVICE_TYPE_TOUCH_PAD,
DEVICE_TYPE_TOUCH_NAVIGATION,
DEVICE_TYPE_GESTURE_SENSOR,
DEVICE_TYPE_POINTER,
};

Expand Down
3 changes: 2 additions & 1 deletion services/sensorservice/SensorService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,10 @@ void SensorService::onFirstRef() {
// available in the HAL
bool needRotationVector =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
bool needOrientation = !needRotationVector && orientationIndex == -1;

registerSensor(new RotationVectorSensor(), !needRotationVector, true);
registerSensor(new OrientationSensor(), !needRotationVector, true);
registerSensor(new OrientationSensor(), !needOrientation, true);

bool needLinearAcceleration =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
Expand Down
4 changes: 4 additions & 0 deletions services/surfaceflinger/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ else
LOCAL_SRC_FILES += \
SurfaceFlinger_hwc1.cpp \
DisplayHardware/HWComposer_hwc1.cpp

ifeq ($(OMAP_ENHANCEMENT),true)
LOCAL_CFLAGS += -DOMAP_ENHANCEMENT
endif
endif

LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
Expand Down
2 changes: 2 additions & 0 deletions services/surfaceflinger/DispSync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <algorithm>

#include <cutils/iosched_policy.h>
#include <log/log.h>
#include <utils/String8.h>
#include <utils/Thread.h>
Expand Down Expand Up @@ -389,6 +390,7 @@ DispSync::DispSync(const char* name) :
ALOGE("Couldn't set SCHED_FIFO for DispSyncThread");
}

android_set_rt_ioprio(mThread->getTid(), 1);

reset();
beginResync();
Expand Down
16 changes: 15 additions & 1 deletion services/surfaceflinger/DisplayDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ DisplayDevice::DisplayDevice(
break;
}

// we store the value as orientation:
// 90 -> 1, 180 -> 2, 270 -> 3
mHardwareRotation = property_get_int32("ro.sf.hwrotation", 0) / 90;

// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);

Expand Down Expand Up @@ -476,6 +480,12 @@ status_t DisplayDevice::orientationToTransfrom(
int orientation, int w, int h, Transform* tr)
{
uint32_t flags = 0;

if (mHardwareRotation && mType == DisplayType::DISPLAY_PRIMARY) {
orientation += mHardwareRotation;
orientation %= 4;
}

switch (orientation) {
case DisplayState::eOrientationDefault:
flags = Transform::ROT_0;
Expand Down Expand Up @@ -531,7 +541,11 @@ void DisplayDevice::setProjection(int orientation,
if (!frame.isValid()) {
// the destination frame can be invalid if it has never been set,
// in that case we assume the whole display frame.
frame = Rect(w, h);
if (mHardwareRotation == 1 || mHardwareRotation == 3) {
frame = Rect(h, w);
} else {
frame = Rect(w, h);
}
}

if (viewport.isEmpty()) {
Expand Down
4 changes: 3 additions & 1 deletion services/surfaceflinger/DisplayDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class DisplayDevice : public LightRefBase<DisplayDevice>
/*
* Transaction state
*/
static status_t orientationToTransfrom(int orientation,
status_t orientationToTransfrom(int orientation,
int w, int h, Transform* tr);

// The identifier of the active layer stack for this display. Several displays
Expand All @@ -265,6 +265,8 @@ class DisplayDevice : public LightRefBase<DisplayDevice>
int mPowerMode;
// Current active config
int mActiveConfig;
// Panel hardware rotation
int32_t mHardwareRotation;
#ifdef USE_HWC2
// current active color mode
android_color_mode_t mActiveColorMode;
Expand Down
19 changes: 19 additions & 0 deletions services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,18 @@ HWComposer::HWComposer(
int fberr = loadFbHalModule();
loadHwcModule();

#ifdef OMAP_ENHANCEMENT
// FB HAL must stay open independent of HWC API version. Closing FB HAL will
// result in destruction of flip chain and de-allocation of framebuffer.
#else
if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// close FB HAL if we don't needed it.
// FIXME: this is temporary until we're not forced to open FB HAL
// before HWC.
framebuffer_close(mFbDev);
mFbDev = NULL;
}
#endif

// If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
Expand Down Expand Up @@ -166,7 +171,11 @@ HWComposer::HWComposer(
}
}

#ifdef OMAP_ENHANCEMENT
if (!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
#else
if (mFbDev) {
#endif
ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
"should only have fbdev if no hwc or hwc is 1.0");

Expand Down Expand Up @@ -424,7 +433,12 @@ status_t HWComposer::queryDisplayProperties(int disp) {
}

// FIXME: what should we set the format to?
#ifdef OMAP_ENHANCEMENT
// Use pixel format native to DSS HW
mDisplayData[disp].format = HAL_PIXEL_FORMAT_BGRA_8888;
#else
mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
#endif
mDisplayData[disp].connected = true;
return NO_ERROR;
}
Expand Down Expand Up @@ -853,7 +867,12 @@ int HWComposer::getVisualID() const {
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
// is supported by the implementation. we can only be in this case
// if we have HWC 1.1
#ifdef OMAP_ENHANCEMENT
// Use pixel format native to DSS HW
return HAL_PIXEL_FORMAT_BGRA_8888;
#else
return HAL_PIXEL_FORMAT_RGBA_8888;
#endif
//return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
} else {
return mFbDev->format;
Expand Down
2 changes: 2 additions & 0 deletions services/surfaceflinger/EventThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <sys/types.h>

#include <cutils/compiler.h>
#include <cutils/iosched_policy.h>

#include <gui/IDisplayEventConnection.h>
#include <gui/DisplayEventReceiver.h>
Expand Down Expand Up @@ -92,6 +93,7 @@ void EventThread::sendVsyncHintOnLocked() {

void EventThread::onFirstRef() {
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
android_set_rt_ioprio(getTid(), 1);
}

sp<EventThread::Connection> EventThread::createEventConnection() const {
Expand Down
41 changes: 29 additions & 12 deletions services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,27 +338,44 @@ void GLES20RenderEngine::disableBlending() {


void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status) {
uint32_t* texName, uint32_t* fbName, uint32_t* status,
bool useReadPixels, int reqWidth, int reqHeight) {
GLuint tname, name;
// turn our EGLImage into a texture
glGenTextures(1, &tname);
glBindTexture(GL_TEXTURE_2D, tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);

// create a Framebuffer Object to render into
glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
if (!useReadPixels) {
// turn our EGLImage into a texture
glGenTextures(1, &tname);
glBindTexture(GL_TEXTURE_2D, tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);

// create a Framebuffer Object to render into
glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
} else {
// since we're going to use glReadPixels() anyways,
// use an intermediate renderbuffer instead
glGenRenderbuffers(1, &tname);
glBindRenderbuffer(GL_RENDERBUFFER, tname);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight);
// create a FBO to render into
glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname);
}

*status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
*texName = tname;
*fbName = name;
}

void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
bool useReadPixels) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbName);
glDeleteTextures(1, &texName);
if (!useReadPixels)
glDeleteTextures(1, &texName);
else
glDeleteRenderbuffers(1, &texName);
}

void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
Expand Down
5 changes: 3 additions & 2 deletions services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ class GLES20RenderEngine : public RenderEngine {
Vector<Group> mGroupStack;

virtual void bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status);
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
uint32_t* texName, uint32_t* fbName, uint32_t* status,
bool useReadPixels, int reqWidth, int reqHeight);
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);

public:
GLES20RenderEngine();
Expand Down
Loading