add skpdiff tool to compare bitmaps
- start framework for pluggable algorithms
- implement simple number of pixels different OpenCL algo
R=djsollen@google.com, bsalomon@google.com, jvanverth@google.com
Author: zachr@google.com
Review URL: https://chromiumcodereview.appspot.com/16284007
git-svn-id: http://skia.googlecode.com/svn/trunk@9616 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/skpdiff/SkCLImageDiffer.h b/experimental/skpdiff/SkCLImageDiffer.h
new file mode 100644
index 0000000..565b371
--- /dev/null
+++ b/experimental/skpdiff/SkCLImageDiffer.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCLImageDiffer_DEFINED
+#define SkCLImageDiffer_DEFINED
+
+#include <CL/cl.h>
+#include "SkTDArray.h"
+
+#include "SkImageDiffer.h"
+
+class SkStream;
+
+/**
+ * An SkImageDiffer that requires initialization with an OpenCL device and context.
+ */
+class SkCLImageDiffer : public SkImageDiffer {
+public:
+ SkCLImageDiffer();
+
+ /**
+ * Initializes the OpenCL resources this differ needs to work
+ * @param device An OpenCL device
+ * @param context An OpenCL context of the given device
+ * @return True on success, false otherwise
+ */
+ virtual bool init(cl_device_id device, cl_context context);
+
+protected:
+ /**
+ * Called by init after fDevice, fContext, and fCommandQueue are successfully initialized
+ * @return True on success, false otherwise
+ */
+ virtual bool onInit() = 0;
+
+ /**
+ * Loads an OpenCL kernel from the file with the given named entry point. This only works after
+ * init is called.
+ * @param file The file path of the kernel
+ * @param name The name of the entry point of the desired kernel in the file
+ * @param kernel A pointer to return the loaded kernel into
+ * @return True on success, false otherwise
+ */
+ bool loadKernelFile(const char file[], const char name[], cl_kernel* kernel);
+
+ /**
+ * Loads an OpenCL kernel from the stream with the given named entry point. This only works
+ * after init is called.
+ * @param stream The stream that contains the kernel
+ * @param name The name of the entry point of the desired kernel in the stream
+ * @param kernel A pointer to return the loaded kernel into
+ * @return True on success, false otherwise
+ */
+ bool loadKernelStream(SkStream* stream, const char name[], cl_kernel* kernel);
+
+ /**
+ * Loads an OpenCL kernel from the source string with the given named entry point. This only
+ * works after init is called.
+ * @param source The string that contains the kernel
+ * @param name The name of the entry point of the desired kernel in the source string
+ * @param kernel A pointer to return the loaded kernel into
+ * @return True on success, false otherwise
+ */
+ bool loadKernelSource(const char source[], const char name[], cl_kernel* kernel);
+
+ /**
+ * Loads a read only copy of the given bitmap into device memory and returns the block of
+ * memory. This only works after init is called.
+ * @param bitmap The bitmap to load into memory
+ * @param image A pointer to return the allocated image to
+ * @return True on success, false otherwise
+ */
+ bool makeImage2D(SkBitmap* bitmap, cl_mem* image);
+
+ cl_device_id fDevice;
+ cl_context fContext;
+ cl_command_queue fCommandQueue;
+
+private:
+
+ typedef SkImageDiffer INHERITED;
+};
+
+/**
+ * A OpenCL differ that measures the percentage of different corresponding pixels. If the two images
+ * are not the same size or have no pixels, the result will always be zero.
+ */
+class SkDifferentPixelsImageDiffer : public SkCLImageDiffer {
+public:
+ virtual const char* getName() SK_OVERRIDE;
+ virtual int queueDiff(SkBitmap* baseline, SkBitmap* test) SK_OVERRIDE;
+ virtual bool isFinished(int id) SK_OVERRIDE;
+ virtual double getResult(int id) SK_OVERRIDE;
+
+protected:
+ virtual bool onInit() SK_OVERRIDE;
+
+private:
+ struct QueuedDiff {
+ bool finished;
+ double result;
+ cl_mem baseline;
+ cl_mem test;
+ cl_mem resultsBuffer;
+ };
+
+ SkTDArray<QueuedDiff> fQueuedDiffs;
+ cl_kernel fKernel;
+
+ typedef SkCLImageDiffer INHERITED;
+};
+
+#endif