diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
new file mode 100644
index 0000000..743dbf1
--- /dev/null
+++ b/opengl/tests/hwc/Android.mk
@@ -0,0 +1,27 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= hwc_stress.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libEGL \
+    libGLESv2 \
+    libui \
+    libhardware \
+
+LOCAL_STATIC_LIBRARIES := \
+    libtestUtil \
+
+LOCAL_C_INCLUDES += \
+    system/extras/tests/include \
+    hardware/libhardware/include \
+
+LOCAL_MODULE:= hwc_stress
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_NATIVE_TEST)
diff --git a/opengl/tests/hwc/hwc_stress.cpp b/opengl/tests/hwc/hwc_stress.cpp
new file mode 100644
index 0000000..d119734
--- /dev/null
+++ b/opengl/tests/hwc/hwc_stress.cpp
@@ -0,0 +1,1193 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ */
+
+/*
+ * Hardware Composer stress test
+ *
+ * Performs a pseudo-random (prandom) sequence of operations to the
+ * Hardware Composer (HWC), for a specified number of passes or for
+ * a specified period of time.  By default the period of time is FLT_MAX,
+ * so that the number of passes will take precedence.
+ *
+ * The passes are grouped together, where (pass / passesPerGroup) specifies
+ * which group a particular pass is in.  This causes every passesPerGroup
+ * worth of sequential passes to be within the same group.  Computationally
+ * intensive operations are performed just once at the beginning of a group
+ * of passes and then used by all the passes in that group.  This is done
+ * so as to increase both the average and peak rate of graphic operations,
+ * by moving computationally intensive operations to the beginning of a group.
+ * In particular, at the start of each group of passes a set of
+ * graphic buffers are created, then used by the first and remaining
+ * passes of that group of passes.
+ *
+ * The per-group initialization of the graphic buffers is performed
+ * by a function called initFrames.  This function creates an array
+ * of smart pointers to the graphic buffers, in the form of a vector
+ * of vectors.  The array is accessed in row major order, so each
+ * row is a vector of smart pointers.  All the pointers of a single
+ * row point to graphic buffers which use the same pixel format and
+ * have the same dimension, although it is likely that each one is
+ * filled with a different color.  This is done so that after doing
+ * the first HWC prepare then set call, subsequent set calls can
+ * be made with each of the layer handles changed to a different
+ * graphic buffer within the same row.  Since the graphic buffers
+ * in a particular row have the same pixel format and dimension,
+ * additional HWC set calls can be made, without having to perform
+ * an HWC prepare call.
+ *
+ * This test supports the following command-line options:
+ *
+ *   -v        Verbose
+ *   -s num    Starting pass
+ *   -e num    Ending pass
+ *   -p num    Execute the single pass specified by num
+ *   -n num    Number of set operations to perform after each prepare operation
+ *   -t float  Maximum time in seconds to execute the test
+ *   -d float  Delay in seconds performed after each set operation
+ *   -D float  Delay in seconds performed after the last pass is executed
+ *
+ * Typically the test is executed for a large range of passes.  By default
+ * passes 0 through 99999 (100,000 passes) are executed.  Although this test
+ * does not validate the generated image, at times it is useful to reexecute
+ * a particular pass and leave the displayed image on the screen for an
+ * extended period of time.  This can be done either by setting the -s
+ * and -e options to the desired pass, along with a large value for -D.
+ * This can also be done via the -p option, again with a large value for
+ * the -D options.
+ *
+ * So far this test only contains code to create graphic buffers with
+ * a continuous solid color.  Although this test is unable to validate the
+ * image produced, any image that contains other than rectangles of a solid
+ * color are incorrect.  Note that the rectangles may use a transparent
+ * color and have a blending operation that causes the color in overlapping
+ * rectangles to be mixed.  In such cases the overlapping portions may have
+ * a different color from the rest of the rectangle.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <libgen.h>
+#include <sched.h>
+#include <sstream>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <vector>
+
+#include <arpa/inet.h> // For ntohl() and htonl()
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#define LOG_TAG "hwcStressTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+using namespace std;
+using namespace android;
+
+const float maxSizeRatio = 1.3;  // Graphic buffers can be upto this munch
+                                 // larger than the default screen size
+const unsigned int passesPerGroup = 10; // A group of passes all use the same
+                                        // graphic buffers
+const float rareRatio = 0.1; // Ratio at which rare conditions are produced.
+
+// Defaults for command-line options
+const bool defaultVerbose = false;
+const unsigned int defaultStartPass = 0;
+const unsigned int defaultEndPass = 99999;
+const unsigned int defaultPerPassNumSet = 10;
+const float defaultPerPassDelay = 0.1;
+const float defaultEndDelay = 2.0; // Default delay between completion of
+                                   // final pass and restart of framework
+const float defaultDuration = FLT_MAX; // A fairly long time, so that
+                                       // range of passes will have
+                                       // precedence
+
+// Command-line option settings
+static bool verbose = defaultVerbose;
+static unsigned int startPass = defaultStartPass;
+static unsigned int endPass = defaultEndPass;
+static unsigned int numSet = defaultPerPassNumSet;
+static float perSetDelay = defaultPerPassDelay;
+static float endDelay = defaultEndDelay;
+static float duration = defaultDuration;
+
+// Command-line mutual exclusion detection flags.
+// Corresponding flag set true once an option is used.
+bool eFlag, sFlag, pFlag;
+
+#define MAXSTR               100
+#define MAXCMD               200
+#define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
+                                 // it has been added
+
+#define CMD_STOP_FRAMEWORK   "stop 2>&1"
+#define CMD_START_FRAMEWORK  "start 2>&1"
+
+#define NUMA(a) (sizeof(a) / sizeof(a [0]))
+#define MEMCLR(addr, size) do { \
+        memset((addr), 0, (size)); \
+    } while (0)
+
+// Represent RGB color as fraction of color components.
+// Each of the color components are expected in the range [0.0, 1.0]
+class RGBColor {
+  public:
+    RGBColor(): _r(0.0), _g(0.0), _b(0.0) {};
+    RGBColor(float f): _r(f), _g(f), _b(f) {}; // Gray
+    RGBColor(float r, float g, float b): _r(r), _g(g), _b(b) {};
+    float r(void) const { return _r; }
+    float g(void) const { return _g; }
+    float b(void) const { return _b; }
+
+  private:
+    float _r;
+    float _g;
+    float _b;
+};
+
+// Represent YUV color as fraction of color components.
+// Each of the color components are expected in the range [0.0, 1.0]
+class YUVColor {
+  public:
+    YUVColor(): _y(0.0), _u(0.0), _v(0.0) {};
+    YUVColor(float f): _y(f), _u(0.0), _v(0.0) {}; // Gray
+    YUVColor(float y, float u, float v): _y(y), _u(u), _v(v) {};
+    float y(void) const { return _y; }
+    float u(void) const { return _u; }
+    float v(void) const { return _v; }
+
+  private:
+    float _y;
+    float _u;
+    float _v;
+};
+
+// File scope constants
+static const struct {
+    unsigned int format;
+    const char *desc;
+} graphicFormat[] = {
+    {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888"},
+    {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888"},
+//    {HAL_PIXEL_FORMAT_RGB_888, "RGB888"},  // Known issue: 3198458
+    {HAL_PIXEL_FORMAT_RGB_565, "RGB565"},
+    {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888"},
+    {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551"},
+    {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444"},
+//    {HAL_PIXEL_FORMAT_YV12, "YV12"}, // Currently not supported by HWC
+};
+const unsigned int blendingOps[] = {
+    HWC_BLENDING_NONE,
+    HWC_BLENDING_PREMULT,
+    HWC_BLENDING_COVERAGE,
+};
+const unsigned int layerFlags[] = {
+    HWC_SKIP_LAYER,
+};
+const vector<unsigned int> vecLayerFlags(layerFlags,
+    layerFlags + NUMA(layerFlags));
+
+const unsigned int transformFlags[] = {
+    HWC_TRANSFORM_FLIP_H,
+    HWC_TRANSFORM_FLIP_V,
+    HWC_TRANSFORM_ROT_90,
+    // ROT_180 & ROT_270 intentionally not listed, because they
+    // they are formed from combinations of the flags already listed.
+};
+const vector<unsigned int> vecTransformFlags(transformFlags,
+    transformFlags + NUMA(transformFlags));
+
+// File scope globals
+static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+static hw_module_t const *hwcModule;
+static hwc_composer_device_t *hwcDevice;
+static vector <vector <sp<GraphicBuffer> > > frames;
+static EGLDisplay dpy;
+static EGLContext context;
+static EGLSurface surface;
+static EGLint width, height;
+
+// File scope prototypes
+static void execCmd(const char *cmd);
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
+static void checkGlError(const char* op);
+static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config);
+static void printGLString(const char *name, GLenum s);
+static hwc_layer_list_t *createLayerList(size_t numLayers);
+static void freeLayerList(hwc_layer_list_t *list);
+static void fillColor(GraphicBuffer *gBuf, RGBColor color, float trans);
+static void fillColor(GraphicBuffer *gBuf, YUVColor color, float trans);
+void init(void);
+void initFrames(unsigned int seed);
+void displayList(hwc_layer_list_t *list);
+void displayListPrepareModifiable(hwc_layer_list_t *list);
+void displayListHandles(hwc_layer_list_t *list);
+const char *graphicFormat2str(unsigned int format);
+template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num);
+template <class T> T vectorOr(const vector<T>& vec);
+
+/*
+ * Main
+ *
+ * Performs the following high-level sequence of operations:
+ *
+ *   1. Command-line parsing
+ *
+ *   2. Initialization
+ *
+ *   3. For each pass:
+ *
+ *        a. If pass is first pass or in a different group from the
+ *           previous pass, initialize the array of graphic buffers.
+ *
+ *        b. Create a HWC list with room to specify a prandomly
+ *           selected number of layers.
+ *
+ *        c. Select a subset of the rows from the graphic buffer array,
+ *           such that there is a unique row to be used for each
+ *           of the layers in the HWC list.
+ *
+ *        d. Prandomly fill in the HWC list with handles
+ *           selected from any of the columns of the selected row.
+ *
+ *        e. Pass the populated list to the HWC prepare call.
+ *
+ *        f. Pass the populated list to the HWC set call.
+ *
+ *        g. If additional set calls are to be made, then for each
+ *           additional set call, select a new set of handles and
+ *           perform the set call.
+ */
+int
+main(int argc, char *argv[])
+{
+    int rv, opt;
+    char *chptr;
+    unsigned int pass;
+    char cmd[MAXCMD];
+    struct timeval startTime, currentTime, delta;
+
+    testSetLogCatTag(LOG_TAG);
+
+    // Parse command line arguments
+    while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) {
+        switch (opt) {
+          case 'd': // Delay after each set operation
+            perSetDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (perSetDelay < 0.0)) {
+                testPrintE("Invalid command-line specified per pass delay of: "
+                           "%s", optarg);
+                exit(1);
+            }
+            break;
+
+          case 'D': // End of test delay
+                    // Delay between completion of final pass and restart
+                    // of framework
+            endDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (endDelay < 0.0)) {
+                testPrintE("Invalid command-line specified end of test delay "
+                           "of: %s", optarg);
+                exit(2);
+            }
+            break;
+
+          case 't': // Duration
+            duration = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (duration < 0.0)) {
+                testPrintE("Invalid command-line specified duration of: %s",
+                           optarg);
+                exit(3);
+            }
+            break;
+
+          case 'n': // Num set operations per pass
+            numSet = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified num set per pass "
+                           "of: %s", optarg);
+                exit(4);
+            }
+            break;
+
+          case 's': // Starting Pass
+            sFlag = true;
+            if (pFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(5);
+            }
+            startPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified starting pass "
+                           "of: %s", optarg);
+                exit(6);
+            }
+            break;
+
+          case 'e': // Ending Pass
+            eFlag = true;
+            if (pFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(7);
+            }
+            endPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified ending pass "
+                           "of: %s", optarg);
+                exit(8);
+            }
+            break;
+
+          case 'p': // Run a single specified pass
+            pFlag = true;
+            if (sFlag || eFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(9);
+            }
+            startPass = endPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified pass of: %s",
+                           optarg);
+                exit(10);
+            }
+            break;
+
+          case 'v': // Verbose
+            verbose = true;
+            break;
+
+          case 'h': // Help
+          case '?':
+          default:
+            testPrintE("  %s [options]", basename(argv[0]));
+            testPrintE("    options:");
+            testPrintE("      -p Execute specified pass");
+            testPrintE("      -s Starting pass");
+            testPrintE("      -e Ending pass");
+            testPrintE("      -t Duration");
+            testPrintE("      -d Delay after each set operation");
+            testPrintE("      -D End of test delay");
+            testPrintE("      -n Num set operations per pass");
+            testPrintE("      -v Verbose");
+            exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
+        }
+    }
+    if (endPass < startPass) {
+        testPrintE("Unexpected ending pass before starting pass");
+        testPrintE("  startPass: %u endPass: %u", startPass, endPass);
+        exit(12);
+    }
+    if (argc != optind) {
+        testPrintE("Unexpected command-line postional argument");
+        testPrintE("  %s [-s start_pass] [-e end_pass] [-t duration]",
+            basename(argv[0]));
+        exit(13);
+    }
+    testPrintI("duration: %g", duration);
+    testPrintI("startPass: %u", startPass);
+    testPrintI("endPass: %u", endPass);
+    testPrintI("numSet: %u", numSet);
+
+    // Stop framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
+        exit(14);
+    }
+    execCmd(cmd);
+    testDelay(1.0); // TODO - needs means to query whether asyncronous stop
+                    // framework operation has completed.  For now, just wait
+                    // a long time.
+
+    init();
+
+    // For each pass
+    gettimeofday(&startTime, NULL);
+    for (pass = startPass; pass <= endPass; pass++) {
+        // Stop if duration of work has already been performed
+        gettimeofday(&currentTime, NULL);
+        delta = tvDelta(&startTime, &currentTime);
+        if (tv2double(&delta) > duration) { break; }
+
+        // Regenerate a new set of test frames when this pass is
+        // either the first pass or is in a different group then
+        // the previous pass.  A group of passes are passes that
+        // all have the same quotient when their pass number is
+        // divided by passesPerGroup.
+        if ((pass == startPass)
+            || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) {
+            initFrames(pass / passesPerGroup);
+        }
+
+        testPrintI("==== Starting pass: %u", pass);
+
+        // Cause deterministic sequence of prandom numbers to be
+        // generated for this pass.
+        srand48(pass);
+
+        hwc_layer_list_t *list;
+        list = createLayerList(testRandMod(frames.size()) + 1);
+        if (list == NULL) {
+            testPrintE("createLayerList failed");
+            exit(20);
+        }
+
+	// Prandomly select a subset of frames to be used by this pass.
+        vector <vector <sp<GraphicBuffer> > > selectedFrames;
+        selectedFrames = vectorRandSelect(frames, list->numHwLayers);
+
+        // Any transform tends to create a layer that the hardware
+        // composer is unable to support and thus has to leave for
+        // SurfaceFlinger.  Place heavy bias on specifying no transforms.
+        bool noTransform = testRandFract() > rareRatio;
+
+        for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
+            unsigned int idx = testRandMod(selectedFrames[n1].size());
+            sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
+            hwc_layer_t *layer = &list->hwLayers[n1];
+            layer->handle = gBuf->handle;
+
+            layer->blending = blendingOps[testRandMod(NUMA(blendingOps))];
+            layer->flags = (testRandFract() > rareRatio) ? 0
+                : vectorOr(vectorRandSelect(vecLayerFlags,
+                           testRandMod(vecLayerFlags.size() + 1)));
+            layer->transform = (noTransform || testRandFract() > rareRatio) ? 0
+                : vectorOr(vectorRandSelect(vecTransformFlags,
+                           testRandMod(vecTransformFlags.size() + 1)));
+            layer->sourceCrop.left = testRandMod(gBuf->getWidth());
+            layer->sourceCrop.top = testRandMod(gBuf->getHeight());
+            layer->sourceCrop.right = layer->sourceCrop.left
+                + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1;
+            layer->sourceCrop.bottom = layer->sourceCrop.top
+                + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1;
+            layer->displayFrame.left = testRandMod(width);
+            layer->displayFrame.top = testRandMod(height);
+            layer->displayFrame.right = layer->displayFrame.left
+                + testRandMod(width - layer->displayFrame.left) + 1;
+            layer->displayFrame.bottom = layer->displayFrame.top
+                + testRandMod(height - layer->displayFrame.top) + 1;
+            layer->visibleRegionScreen.numRects = 1;
+            layer->visibleRegionScreen.rects = &layer->displayFrame;
+        }
+
+        // Perform prepare operation
+        if (verbose) { testPrintI("Prepare:"); displayList(list); }
+        hwcDevice->prepare(hwcDevice, list);
+        if (verbose) {
+            testPrintI("Post Prepare:");
+            displayListPrepareModifiable(list);
+        }
+
+        // Turn off the geometry changed flag
+        list->flags &= ~HWC_GEOMETRY_CHANGED;
+
+        // Perform the set operation(s)
+        if (verbose) {testPrintI("Set:"); }
+        for (unsigned int n1 = 0; n1 < numSet; n1++) {
+            if (verbose) {displayListHandles(list); }
+            hwcDevice->set(hwcDevice, dpy, surface, list);
+
+            // Prandomly select a new set of handles
+            for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
+                unsigned int idx = testRandMod(selectedFrames[n1].size());
+                sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
+                hwc_layer_t *layer = &list->hwLayers[n1];
+                layer->handle = (native_handle_t *) gBuf->handle;
+            }
+
+            testDelay(perSetDelay);
+        }
+
+
+        freeLayerList(list);
+        testPrintI("==== Completed pass: %u", pass);
+    }
+
+    testDelay(endDelay);
+
+    // Start framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
+        exit(21);
+    }
+    execCmd(cmd);
+
+    testPrintI("Successfully completed %u passes", pass - startPass);
+
+    return 0;
+}
+
+/*
+ * Execute Command
+ *
+ * Executes the command pointed to by cmd.  Output from the
+ * executed command is captured and sent to LogCat Info.  Once
+ * the command has finished execution, it's exit status is captured
+ * and checked for an exit status of zero.  Any other exit status
+ * causes diagnostic information to be printed and an immediate
+ * testcase failure.
+ */
+static void execCmd(const char *cmd)
+{
+    FILE *fp;
+    int rv;
+    int status;
+    char str[MAXSTR];
+
+    // Display command to be executed
+    testPrintI("cmd: %s", cmd);
+
+    // Execute the command
+    fflush(stdout);
+    if ((fp = popen(cmd, "r")) == NULL) {
+        testPrintE("execCmd popen failed, errno: %i", errno);
+        exit(30);
+    }
+
+    // Obtain and display each line of output from the executed command
+    while (fgets(str, sizeof(str), fp) != NULL) {
+        if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
+            str[strlen(str) - 1] = '\0';
+        }
+        testPrintI(" out: %s", str);
+    }
+
+    // Obtain and check return status of executed command.
+    // Fail on non-zero exit status
+    status = pclose(fp);
+    if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
+        testPrintE("Unexpected command failure");
+        testPrintE("  status: %#x", status);
+        if (WIFEXITED(status)) {
+            testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
+        }
+        if (WIFSIGNALED(status)) {
+            testPrintE("WTERMSIG: %i", WTERMSIG(status));
+        }
+        exit(31);
+    }
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal) {
+    if (returnVal != EGL_TRUE) {
+        testPrintE("%s() returned %d", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        testPrintE("after %s() eglError %s (0x%x)",
+                   op, EGLUtils::strerror(error), error);
+    }
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        testPrintE("after %s() glError (0x%x)", op, error);
+    }
+}
+
+static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            testPrintI(" %s: %d (%#x)", names[j].name, value, value);
+        }
+    }
+    testPrintI("");
+}
+
+static void printGLString(const char *name, GLenum s)
+{
+    const char *v = (const char *) glGetString(s);
+
+    if (v == NULL) {
+        testPrintI("GL %s unknown", name);
+    } else {
+        testPrintI("GL %s = %s", name, v);
+    }
+}
+
+/*
+ * createLayerList
+ * dynamically creates layer list with numLayers worth
+ * of hwLayers entries.
+ */
+static hwc_layer_list_t *createLayerList(size_t numLayers)
+{
+    hwc_layer_list_t *list;
+
+    size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t);
+    if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) {
+        return NULL;
+    }
+    list->flags = HWC_GEOMETRY_CHANGED;
+    list->numHwLayers = numLayers;
+
+    return list;
+}
+
+/*
+ * freeLayerList
+ * Frees memory previous allocated via createLayerList().
+ */
+static void freeLayerList(hwc_layer_list_t *list)
+{
+    free(list);
+}
+
+static void fillColor(GraphicBuffer *gBuf, RGBColor color, float trans)
+{
+    unsigned char* buf = NULL;
+    status_t err;
+    unsigned int numPixels = gBuf->getWidth() * gBuf->getHeight();
+    uint32_t pixel;
+
+    // RGB 2 YUV conversion ratios
+    const struct rgb2yuvRatios {
+        int format;
+        float weightRed;
+        float weightBlu;
+        float weightGrn;
+    } rgb2yuvRatios[] = {
+        { HAL_PIXEL_FORMAT_YV12, 0.299, 0.114, 0.587 },
+    };
+
+    const struct rgbAttrib {
+        int format;
+        bool   hostByteOrder;
+        size_t bytes;
+        size_t rOffset;
+        size_t rSize;
+        size_t gOffset;
+        size_t gSize;
+        size_t bOffset;
+        size_t bSize;
+        size_t aOffset;
+        size_t aSize;
+    } rgbAttributes[] = {
+        {HAL_PIXEL_FORMAT_RGBA_8888, false, 4,  0, 8,  8, 8, 16, 8, 24, 8},
+        {HAL_PIXEL_FORMAT_RGBX_8888, false, 4,  0, 8,  8, 8, 16, 8,  0, 0},
+        {HAL_PIXEL_FORMAT_RGB_888,   false, 3,  0, 8,  8, 8, 16, 8,  0, 0},
+        {HAL_PIXEL_FORMAT_RGB_565,   true,  2,  0, 5,  5, 6, 11, 5,  0, 0},
+        {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8,  8, 8,  0, 8, 24, 8},
+        {HAL_PIXEL_FORMAT_RGBA_5551, true , 2,  0, 5,  5, 5, 10, 5, 15, 1},
+        {HAL_PIXEL_FORMAT_RGBA_4444, false, 2, 12, 4,  0, 4,  4, 4,  8, 4},
+    };
+
+    // If YUV format, convert color and pass work to YUV color fill
+    for (unsigned int n1 = 0; n1 < NUMA(rgb2yuvRatios); n1++) {
+        if (gBuf->getPixelFormat() == rgb2yuvRatios[n1].format) {
+            float wr = rgb2yuvRatios[n1].weightRed;
+            float wb = rgb2yuvRatios[n1].weightBlu;
+            float wg = rgb2yuvRatios[n1].weightGrn;
+            float y = wr * color.r() + wb * color.b() + wg * color.g();
+            float u = 0.5 * ((color.b() - y) / (1 - wb)) + 0.5;
+            float v = 0.5 * ((color.r() - y) / (1 - wr)) + 0.5;
+            YUVColor yuvColor(y, u, v);
+            fillColor(gBuf, yuvColor, trans);
+            return;
+        }
+    }
+
+    const struct rgbAttrib *attrib;
+    for (attrib = rgbAttributes; attrib < rgbAttributes + NUMA(rgbAttributes);
+         attrib++) {
+        if (attrib->format == gBuf->getPixelFormat()) { break; }
+    }
+    if (attrib >= rgbAttributes + NUMA(rgbAttributes)) {
+        testPrintE("fillColor rgb unsupported format of: %u",
+        gBuf->getPixelFormat());
+        exit(50);
+    }
+
+    pixel = htonl((uint32_t) (((1 << attrib->rSize) - 1) * color.r())
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->rOffset + attrib->rSize)));
+    pixel |= htonl((uint32_t) (((1 << attrib->gSize) - 1) * color.g())
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->gOffset + attrib->gSize)));
+    pixel |= htonl((uint32_t) (((1 << attrib->bSize) - 1) * color.b())
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->bOffset + attrib->bSize)));
+    if (attrib->aSize) {
+        pixel |= htonl((uint32_t) (((1 << attrib->aSize) - 1) * trans)
+             << ((sizeof(pixel) * BITSPERBYTE)
+                 - (attrib->aOffset + attrib->aSize)));
+    }
+    if (attrib->hostByteOrder) {
+        pixel = ntohl(pixel);
+        pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE;
+    }
+
+    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        testPrintE("fillColor rgb lock failed: %d", err);
+        exit(51);
+    }
+
+    for (unsigned int n1 = 0; n1 < numPixels; n1++) {
+        memmove(buf, &pixel, attrib->bytes);
+        buf += attrib->bytes;
+    }
+
+    err = gBuf->unlock();
+    if (err != 0) {
+        testPrintE("fillColor rgb unlock failed: %d", err);
+        exit(52);
+    }
+}
+
+static void fillColor(GraphicBuffer *gBuf, YUVColor color, float trans)
+{
+    unsigned char* buf = NULL;
+    status_t err;
+    unsigned int width = gBuf->getWidth();
+    unsigned int height = gBuf->getHeight();
+
+    const struct yuvAttrib {
+        int format;
+        size_t padWidth;
+        bool   planar;
+        unsigned int uSubSampX;
+        unsigned int uSubSampY;
+        unsigned int vSubSampX;
+        unsigned int vSubSampY;
+    } yuvAttributes[] = {
+        { HAL_PIXEL_FORMAT_YV12, 16, true, 2, 2, 2, 2},
+    };
+
+    const struct yuvAttrib *attrib;
+    for (attrib = yuvAttributes; attrib < yuvAttributes + NUMA(yuvAttributes);
+         attrib++) {
+        if (attrib->format == gBuf->getPixelFormat()) { break; }
+    }
+    if (attrib >= yuvAttributes + NUMA(yuvAttributes)) {
+        testPrintE("fillColor yuv unsupported format of: %u",
+        gBuf->getPixelFormat());
+        exit(60);
+    }
+
+    assert(attrib->planar == true); // So far, only know how to handle planar
+
+    // If needed round width up to pad size
+    if (width % attrib->padWidth) {
+        width += attrib->padWidth - (width % attrib->padWidth);
+    }
+    assert((width % attrib->padWidth) == 0);
+
+    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        testPrintE("fillColor lock failed: %d", err);
+        exit(61);
+    }
+
+    // Fill in Y component
+    for (unsigned int x = 0; x < width; x++) {
+        for (unsigned int y = 0; y < height; y++) {
+            *buf++ = (x < gBuf->getWidth()) ? (255 * color.y()) : 0;
+        }
+    }
+
+    // Fill in U component
+    for (unsigned int x = 0; x < width; x += attrib->uSubSampX) {
+        for (unsigned int y = 0; y < height; y += attrib->uSubSampY) {
+            *buf++ = (x < gBuf->getWidth()) ? (255 * color.u()) : 0;
+        }
+    }
+
+    // Fill in V component
+    for (unsigned int x = 0; x < width; x += attrib->vSubSampX) {
+        for (unsigned int y = 0; y < height; y += attrib->vSubSampY) {
+            *buf++ = (x < gBuf->getWidth()) ? (255 * color.v()) : 0;
+        }
+    }
+
+    err = gBuf->unlock();
+    if (err != 0) {
+        testPrintE("fillColor unlock failed: %d", err);
+        exit(62);
+    }
+}
+
+void init(void)
+{
+    int rv;
+
+    EGLBoolean returnValue;
+    EGLConfig myConfig = {0};
+    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint sConfigAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE };
+    EGLint majorVersion, minorVersion;
+
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        testPrintE("eglGetDisplay returned EGL_NO_DISPLAY");
+        exit(70);
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    testPrintI("EGL version %d.%d", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        testPrintE("eglInitialize failed");
+        exit(71);
+    }
+
+    EGLNativeWindowType window = android_createDisplaySurface();
+    if (window == NULL) {
+        testPrintE("android_createDisplaySurface failed");
+        exit(72);
+    }
+    returnValue = EGLUtils::selectConfigForNativeWindow(dpy,
+        sConfigAttribs, window, &myConfig);
+    if (returnValue) {
+        testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d",
+            returnValue);
+        exit(73);
+    }
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    testPrintI("Chose this configuration:");
+    printEGLConfiguration(dpy, myConfig);
+
+    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        testPrintE("gelCreateWindowSurface failed.");
+        exit(74);
+    }
+
+    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, contextAttribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        testPrintE("eglCreateContext failed");
+        exit(75);
+    }
+    returnValue = eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        testPrintE("eglMakeCurrent failed");
+        exit(76);
+    }
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &width);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &height);
+    checkEglError("eglQuerySurface");
+
+    fprintf(stderr, "Window dimensions: %d x %d", width, height);
+
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
+
+    if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) {
+        testPrintE("hw_get_module failed, rv: %i", rv);
+        errno = -rv;
+        perror(NULL);
+        exit(77);
+    }
+    if ((rv = hwc_open(hwcModule, &hwcDevice)) != 0) {
+        testPrintE("hwc_open failed, rv: %i", rv);
+        errno = -rv;
+        perror(NULL);
+        exit(78);
+    }
+
+    testPrintI("");
+}
+
+/*
+ * Initialize Frames
+ *
+ * Creates an array of graphic buffers, within the global variable
+ * named frames.  The graphic buffers are contained within a vector of
+ * verctors.  All the graphic buffers in a particular row are of the same
+ * format and dimension.  Each graphic buffer is uniformly filled with a
+ * prandomly selected color.  It is likely that each buffer, even
+ * in the same row, will be filled with a unique color.
+ */
+void initFrames(unsigned int seed)
+{
+    const size_t maxRows = 5;
+    const size_t minCols = 2;  // Need at least double buffering
+    const size_t maxCols = 4;  // One more than triple buffering
+
+    if (verbose) { testPrintI("initFrames seed: %u", seed); }
+    srand48(seed);
+    size_t rows = testRandMod(maxRows) + 1;
+
+    frames.clear();
+    frames.resize(rows);
+
+    for (unsigned int row = 0; row < rows; row++) {
+        // All frames within a row have to have the same format and
+        // dimensions.  Width and height need to be >= 1.
+        int format = graphicFormat[testRandMod(NUMA(graphicFormat))].format;
+        size_t w = (width * maxSizeRatio) * testRandFract();
+        size_t h = (height * maxSizeRatio) * testRandFract();
+        w = max(1u, w);
+        h = max(1u, h);
+        if (verbose) {
+            testPrintI("  frame %u width: %u height: %u format: %u %s",
+                       row, w, h, format, graphicFormat2str(format));
+        }
+
+        size_t cols = testRandMod((maxCols + 1) - minCols) + minCols;
+        frames[row].resize(cols);
+        for (unsigned int col = 0; col < cols; col++) {
+            RGBColor color(testRandFract(), testRandFract(), testRandFract());
+            float transp = testRandFract();
+
+            frames[row][col] = new GraphicBuffer(w, h, format, texUsage);
+            fillColor(frames[row][col].get(), color, transp);
+            if (verbose) {
+                testPrintI("    buf: %p handle: %p color: <%f, %f, %f> "
+                           "transp: %f",
+                           frames[row][col].get(), frames[row][col]->handle,
+                           color.r(), color.g(), color.b(), transp);
+            }
+        }
+    }
+}
+
+void displayList(hwc_layer_list_t *list)
+{
+    testPrintI("  flags: %#x%s", list->flags,
+               (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : "");
+    testPrintI("  numHwLayers: %u", list->numHwLayers);
+
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        testPrintI("    layer %u compositionType: %#x%s%s", layer,
+                   list->hwLayers[layer].compositionType,
+                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
+                       ? " FRAMEBUFFER" : "",
+                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
+                       ? " OVERLAY" : "");
+
+        testPrintI("      hints: %#x",
+                   list->hwLayers[layer].hints,
+                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
+                       ? " TRIPLE_BUFFER" : "",
+                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
+                       ? " CLEAR_FB" : "");
+
+        testPrintI("      flags: %#x%s",
+                   list->hwLayers[layer].flags,
+                   (list->hwLayers[layer].flags & HWC_SKIP_LAYER)
+                       ? " SKIP_LAYER" : "");
+
+        testPrintI("      handle: %p",
+                   list->hwLayers[layer].handle);
+
+        // Intentionally skipped display of ROT_180 & ROT_270,
+        // which are formed from combinations of the other flags.
+        testPrintI("      transform: %#x%s%s%s",
+                   list->hwLayers[layer].transform,
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H)
+                       ? " FLIP_H" : "",
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V)
+                       ? " FLIP_V" : "",
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90)
+                       ? " ROT_90" : "");
+
+        testPrintI("      blending: %#x",
+                   list->hwLayers[layer].blending,
+                   (list->hwLayers[layer].blending == HWC_BLENDING_NONE)
+                       ? " NONE" : "",
+                   (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT)
+                       ? " PREMULT" : "",
+                   (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE)
+                       ? " COVERAGE" : "");
+
+        testPrintI("      sourceCrop: [%i, %i, %i, %i]",
+                   list->hwLayers[layer].sourceCrop.left,
+                   list->hwLayers[layer].sourceCrop.top,
+                   list->hwLayers[layer].sourceCrop.right,
+                   list->hwLayers[layer].sourceCrop.bottom);
+
+        testPrintI("      displayFrame: [%i, %i, %i, %i]",
+                   list->hwLayers[layer].displayFrame.left,
+                   list->hwLayers[layer].displayFrame.top,
+                   list->hwLayers[layer].displayFrame.right,
+                   list->hwLayers[layer].displayFrame.bottom);
+    }
+}
+
+/*
+ * Display List Prepare Modifiable
+ *
+ * Displays the portions of a list that are meant to be modified by
+ * a prepare call.
+ */
+void displayListPrepareModifiable(hwc_layer_list_t *list)
+{
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        testPrintI("    layer %u compositionType: %#x%s%s", layer,
+                   list->hwLayers[layer].compositionType,
+                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
+                       ? " FRAMEBUFFER" : "",
+                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
+                       ? " OVERLAY" : "");
+        testPrintI("      hints: %#x%s%s",
+                   list->hwLayers[layer].hints,
+                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
+                       ? " TRIPLE_BUFFER" : "",
+                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
+                       ? " CLEAR_FB" : "");
+    }
+}
+
+/*
+ * Display List Handles
+ *
+ * Displays the handles of all the graphic buffers in the list.
+ */
+void displayListHandles(hwc_layer_list_t *list)
+{
+    const unsigned int maxLayersPerLine = 6;
+
+    ostringstream str("  layers:");
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        str << ' ' << list->hwLayers[layer].handle;
+        if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1))
+            && (layer != list->numHwLayers - 1)) {
+            testPrintI("%s", str.str().c_str());
+            str.str("    ");
+        }
+    }
+    testPrintI("%s", str.str().c_str());
+}
+
+const char *graphicFormat2str(unsigned int format)
+{
+    const static char *unknown = "unknown";
+
+    for (unsigned int n1 = 0; n1 < NUMA(graphicFormat); n1++) {
+        if (format == graphicFormat[n1].format) {
+            return graphicFormat[n1].desc;
+        }
+    }
+
+    return unknown;
+}
+
+/*
+ * Vector Random Select
+ *
+ * Prandomly selects and returns num elements from vec.
+ */
+template <class T>
+vector<T> vectorRandSelect(const vector<T>& vec, size_t num)
+{
+    vector<T> rv = vec;
+
+    while (rv.size() > num) {
+        rv.erase(rv.begin() + testRandMod(rv.size()));
+    }
+
+    return rv;
+}
+
+/*
+ * Vector Or
+ *
+ * Or's togethen the values of each element of vec and returns the result.
+ */
+template <class T>
+T vectorOr(const vector<T>& vec)
+{
+    T rv = 0;
+
+    for (size_t n1 = 0; n1 < vec.size(); n1++) {
+        rv |= vec[n1];
+    }
+
+    return rv;
+}
