Merge "BufferQueue: Allow detaching/reattaching buffers"
diff --git a/cmds/screenshot/Android.mk b/cmds/screenshot/Android.mk
deleted file mode 100644
index 1ee7807..0000000
--- a/cmds/screenshot/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := screenshot.c
-
-LOCAL_MODULE := screenshot
-
-LOCAL_SHARED_LIBRARIES := libcutils libz liblog
-LOCAL_STATIC_LIBRARIES := libpng
-LOCAL_C_INCLUDES += external/zlib external/libpng
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/screenshot/screenshot.c b/cmds/screenshot/screenshot.c
deleted file mode 100644
index be1ecd4..0000000
--- a/cmds/screenshot/screenshot.c
+++ /dev/null
@@ -1,171 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <linux/fb.h>
-
-#include <zlib.h>
-#include <png.h>
-
-#include "private/android_filesystem_config.h"
-
-#define LOG_TAG "screenshot"
-#include <utils/Log.h>
-
-void take_screenshot(FILE *fb_in, FILE *fb_out) {
- int fb;
- char imgbuf[0x10000];
- struct fb_var_screeninfo vinfo;
- png_structp png;
- png_infop info;
- unsigned int r,c,rowlen;
- unsigned int bytespp,offset;
-
- fb = fileno(fb_in);
- if(fb < 0) {
- ALOGE("failed to open framebuffer\n");
- return;
- }
- fb_in = fdopen(fb, "r");
-
- if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) {
- ALOGE("failed to get framebuffer info\n");
- return;
- }
- fcntl(fb, F_SETFD, FD_CLOEXEC);
-
- png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png == NULL) {
- ALOGE("failed png_create_write_struct\n");
- fclose(fb_in);
- return;
- }
-
- png_init_io(png, fb_out);
- info = png_create_info_struct(png);
- if (info == NULL) {
- ALOGE("failed png_create_info_struct\n");
- png_destroy_write_struct(&png, NULL);
- fclose(fb_in);
- return;
- }
- if (setjmp(png_jmpbuf(png))) {
- ALOGE("failed png setjmp\n");
- png_destroy_write_struct(&png, NULL);
- fclose(fb_in);
- return;
- }
-
- bytespp = vinfo.bits_per_pixel / 8;
- png_set_IHDR(png, info,
- vinfo.xres, vinfo.yres, vinfo.bits_per_pixel / 4,
- PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- png_write_info(png, info);
-
- rowlen=vinfo.xres * bytespp;
- if (rowlen > sizeof(imgbuf)) {
- ALOGE("crazy rowlen: %d\n", rowlen);
- png_destroy_write_struct(&png, NULL);
- fclose(fb_in);
- return;
- }
-
- offset = vinfo.xoffset * bytespp + vinfo.xres * vinfo.yoffset * bytespp;
- fseek(fb_in, offset, SEEK_SET);
-
- for(r=0; r<vinfo.yres; r++) {
- int len = fread(imgbuf, 1, rowlen, fb_in);
- if (len <= 0) break;
- png_write_row(png, (png_bytep)imgbuf);
- }
-
- png_write_end(png, info);
- fclose(fb_in);
- png_destroy_write_struct(&png, NULL);
-}
-
-void fork_sound(const char* path) {
- pid_t pid = fork();
- if (pid == 0) {
- execl("/system/bin/stagefright", "stagefright", "-o", "-a", path, NULL);
- }
-}
-
-void usage() {
- fprintf(stderr,
- "usage: screenshot [-s soundfile] filename.png\n"
- " -s: play a sound effect to signal success\n"
- " -i: autoincrement to avoid overwriting filename.png\n"
- );
-}
-
-int main(int argc, char**argv) {
- FILE *png = NULL;
- FILE *fb_in = NULL;
- char outfile[PATH_MAX] = "";
-
- char * soundfile = NULL;
- int do_increment = 0;
-
- int c;
- while ((c = getopt(argc, argv, "s:i")) != -1) {
- switch (c) {
- case 's': soundfile = optarg; break;
- case 'i': do_increment = 1; break;
- case '?':
- case 'h':
- usage(); exit(1);
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc < 1) {
- usage(); exit(1);
- }
-
- strlcpy(outfile, argv[0], PATH_MAX);
- if (do_increment) {
- struct stat st;
- char base[PATH_MAX] = "";
- int i = 0;
- while (stat(outfile, &st) == 0) {
- if (!base[0]) {
- char *p = strrchr(outfile, '.');
- if (p) *p = '\0';
- strcpy(base, outfile);
- }
- snprintf(outfile, PATH_MAX, "%s-%d.png", base, ++i);
- }
- }
-
- fb_in = fopen("/dev/graphics/fb0", "r");
- if (!fb_in) {
- fprintf(stderr, "error: could not read framebuffer\n");
- exit(1);
- }
-
- /* switch to non-root user and group */
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW };
- setgroups(sizeof(groups)/sizeof(groups[0]), groups);
- setuid(AID_SHELL);
-
- png = fopen(outfile, "w");
- if (!png) {
- fprintf(stderr, "error: writing file %s: %s\n",
- outfile, strerror(errno));
- exit(1);
- }
-
- take_screenshot(fb_in, png);
-
- if (soundfile) {
- fork_sound(soundfile);
- }
-
- exit(0);
-}
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 5eaf00b..05b1a9c 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -218,6 +218,17 @@
}
+// -- TouchAffineTransformation --
+void TouchAffineTransformation::applyTo(float& x, float& y) const {
+ float newX, newY;
+ newX = x * x_scale + y * x_ymix + x_offset;
+ newY = x * y_xmix + y * y_scale + y_offset;
+
+ x = newX;
+ y = newY;
+}
+
+
// --- InputReader ---
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
@@ -2642,6 +2653,7 @@
dumpVirtualKeys(dump);
dumpRawPointerAxes(dump);
dumpCalibration(dump);
+ dumpAffineTransformation(dump);
dumpSurface(dump);
dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
@@ -2740,6 +2752,11 @@
resolveCalibration();
}
+ if (!changes || (changes & InputReaderConfiguration::TOUCH_AFFINE_TRANSFORMATION)) {
+ // Update location calibration to reflect current settings
+ updateAffineTransformation();
+ }
+
if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
// Update pointer speed.
mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
@@ -3265,6 +3282,9 @@
break;
}
+ // Location
+ updateAffineTransformation();
+
if (mDeviceMode == DEVICE_MODE_POINTER) {
// Compute pointer gesture detection parameters.
float rawDiagonal = hypotf(rawWidth, rawHeight);
@@ -3631,6 +3651,22 @@
}
}
+void TouchInputMapper::dumpAffineTransformation(String8& dump) {
+ dump.append(INDENT3 "Affine Transformation:\n");
+
+ dump.appendFormat(INDENT4 "X scale: %0.3f\n", mAffineTransform.x_scale);
+ dump.appendFormat(INDENT4 "X ymix: %0.3f\n", mAffineTransform.x_ymix);
+ dump.appendFormat(INDENT4 "X offset: %0.3f\n", mAffineTransform.x_offset);
+ dump.appendFormat(INDENT4 "Y xmix: %0.3f\n", mAffineTransform.y_xmix);
+ dump.appendFormat(INDENT4 "Y scale: %0.3f\n", mAffineTransform.y_scale);
+ dump.appendFormat(INDENT4 "Y offset: %0.3f\n", mAffineTransform.y_offset);
+}
+
+void TouchInputMapper::updateAffineTransformation() {
+ mAffineTransform = getPolicy()->getTouchAffineTransformation(mDevice->getDescriptor(),
+ mSurfaceOrientation);
+}
+
void TouchInputMapper::reset(nsecs_t when) {
mCursorButtonAccumulator.reset(getDevice());
mCursorScrollAccumulator.reset(getDevice());
@@ -4246,13 +4282,19 @@
break;
}
- // X, Y, and the bounding box for coverage information
- // Adjust coords for surface orientation.
- float x, y, left, top, right, bottom;
+ // Adjust X,Y coords for device calibration
+ // TODO: Adjust coverage coords?
+ float xTransformed = in.x, yTransformed = in.y;
+ mAffineTransform.applyTo(xTransformed, yTransformed);
+
+ // Adjust X, Y, and coverage coords for surface orientation.
+ float x, y;
+ float left, top, right, bottom;
+
switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
+ x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+ y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
@@ -4263,8 +4305,8 @@
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
- y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
+ x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+ y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
@@ -4275,8 +4317,8 @@
}
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
- y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+ x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+ y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
@@ -4287,8 +4329,8 @@
}
break;
default:
- x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+ x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+ y = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 36b206a..c1ce5f7 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -138,6 +138,9 @@
// The device name alias supplied by the may have changed for some devices.
CHANGE_DEVICE_ALIAS = 1 << 5,
+ // The location calibration matrix changed.
+ TOUCH_AFFINE_TRANSFORMATION = 1 << 6,
+
// All devices must be reopened.
CHANGE_MUST_REOPEN = 1 << 31,
};
@@ -252,6 +255,29 @@
};
+struct TouchAffineTransformation {
+ float x_scale;
+ float x_ymix;
+ float x_offset;
+ float y_xmix;
+ float y_scale;
+ float y_offset;
+
+ TouchAffineTransformation() :
+ x_scale(1.0f), x_ymix(0.0f), x_offset(0.0f),
+ y_xmix(0.0f), y_scale(1.0f), y_offset(0.0f) {
+ }
+
+ TouchAffineTransformation(float xscale, float xymix, float xoffset,
+ float yxmix, float yscale, float yoffset) :
+ x_scale(xscale), x_ymix(xymix), x_offset(xoffset),
+ y_xmix(yxmix), y_scale(yscale), y_offset(yoffset) {
+ }
+
+ void applyTo(float& x, float& y) const;
+};
+
+
/*
* Input reader policy interface.
*
@@ -287,6 +313,10 @@
/* Gets a user-supplied alias for a particular input device, or an empty string if none. */
virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
+
+ /* Gets the affine calibration associated with the specified device. */
+ virtual TouchAffineTransformation getTouchAffineTransformation(
+ const String8& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
};
@@ -518,6 +548,7 @@
inline int32_t getControllerNumber() const { return mControllerNumber; }
inline int32_t getGeneration() const { return mGeneration; }
inline const String8& getName() const { return mIdentifier.name; }
+ inline const String8& getDescriptor() { return mIdentifier.descriptor; }
inline uint32_t getClasses() const { return mClasses; }
inline uint32_t getSources() const { return mSources; }
@@ -1295,6 +1326,9 @@
}
} mCalibration;
+ // Affine location transformation/calibration
+ struct TouchAffineTransformation mAffineTransform;
+
// Raw pointer axis information from the driver.
RawPointerAxes mRawPointerAxes;
@@ -1344,7 +1378,9 @@
virtual void parseCalibration();
virtual void resolveCalibration();
virtual void dumpCalibration(String8& dump);
+ virtual void dumpAffineTransformation(String8& dump);
virtual bool hasStylus() const = 0;
+ virtual void updateAffineTransformation();
virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index aaa973d..c6eb1fd 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -128,6 +128,7 @@
InputReaderConfiguration mConfig;
KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
Vector<InputDeviceInfo> mInputDevices;
+ TouchAffineTransformation transform;
protected:
virtual ~FakeInputReaderPolicy() { }
@@ -173,6 +174,15 @@
return mInputDevices;
}
+ TouchAffineTransformation getTouchAffineTransformation(const String8& inputDeviceDescriptor,
+ int32_t surfaceRotation) {
+ return transform;
+ }
+
+ void setTouchAffineTransformation(const TouchAffineTransformation t) {
+ transform = t;
+ }
+
private:
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
*outConfig = mConfig;
@@ -2463,6 +2473,7 @@
static const float Y_PRECISION;
static const float GEOMETRIC_SCALE;
+ static const TouchAffineTransformation AFFINE_TRANSFORM;
static const VirtualKeyDefinition VIRTUAL_KEYS[2];
@@ -2482,8 +2493,11 @@
void prepareDisplay(int32_t orientation);
void prepareVirtualKeys();
+ void prepareLocationCalibration();
int32_t toRawX(float displayX);
int32_t toRawY(float displayY);
+ float toCookedX(float rawX, float rawY);
+ float toCookedY(float rawX, float rawY);
float toDisplayX(int32_t rawX);
float toDisplayY(int32_t rawY);
};
@@ -2510,6 +2524,8 @@
const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
+const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
+ TouchAffineTransformation(1, -2, 3, -4, 5, -6);
const float TouchInputMapperTest::GEOMETRIC_SCALE =
avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
@@ -2531,6 +2547,10 @@
mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
}
+void TouchInputMapperTest::prepareLocationCalibration() {
+ mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
+}
+
int32_t TouchInputMapperTest::toRawX(float displayX) {
return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
}
@@ -2539,6 +2559,16 @@
return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
}
+float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
+ AFFINE_TRANSFORM.applyTo(rawX, rawY);
+ return rawX;
+}
+
+float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
+ AFFINE_TRANSFORM.applyTo(rawX, rawY);
+ return rawY;
+}
+
float TouchInputMapperTest::toDisplayX(int32_t rawX) {
return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN + 1);
}
@@ -3226,6 +3256,30 @@
ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
}
+TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareLocationCalibration();
+ prepareButtons();
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ int32_t rawX = 100;
+ int32_t rawY = 200;
+
+ float x = toDisplayX(toCookedX(rawX, rawY));
+ float y = toDisplayY(toCookedY(rawX, rawY));
+
+ processDown(mapper, rawX, rawY);
+ processSync(mapper);
+
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+ x, y, 1, 0, 0, 0, 0, 0, 0, 0));
+}
+
TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
addConfigurationProperty("touch.deviceType", "touchScreen");
diff --git a/services/surfaceflinger/Effects/Daltonizer.cpp b/services/surfaceflinger/Effects/Daltonizer.cpp
index f384ba4..feb8936 100644
--- a/services/surfaceflinger/Effects/Daltonizer.cpp
+++ b/services/surfaceflinger/Effects/Daltonizer.cpp
@@ -148,9 +148,6 @@
// set to identity, errp, errd, errt ([0] for simulation only)
mat4 correction(0);
- // control: simulation post-correction (used for debugging):
- // set to identity or lms2lmsp, lms2lmsd, lms2lmst
- mat4 control;
switch (mType) {
case protanopia:
case protanomaly:
@@ -172,12 +169,8 @@
break;
}
- if (true) {
- control = simulation;
- }
-
- mColorTransform = lms2rgb * control *
- (simulation * rgb2lms + correction * (rgb2lms - simulation * rgb2lms));
+ mColorTransform = lms2rgb *
+ (simulation * rgb2lms + correction * (rgb2lms - simulation * rgb2lms));
}
} /* namespace android */