migrate skpdiff to tools
R=djsollen@google.com Review URL: https://codereview.chromium.org/19671002 git-svn-id: http://skia.googlecode.com/svn/trunk@10225 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
14cec91fe1
commit
a54aaf7fba
@ -1,53 +0,0 @@
|
||||
# GYP file to build skpdiff.
|
||||
#
|
||||
# To build on Linux:
|
||||
# ./gyp_skia skpdiff.gyp && make skpdiff
|
||||
#
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'skpdiff',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'main.cpp',
|
||||
'SkDiffContext.cpp',
|
||||
'SkImageDiffer.cpp',
|
||||
'SkPMetric.cpp',
|
||||
'skpdiff_util.cpp',
|
||||
'../../tools/flags/SkCommandLineFlags.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../../tools/flags'
|
||||
],
|
||||
'dependencies': [
|
||||
'../../gyp/skia_lib.gyp:skia_lib',
|
||||
],
|
||||
'cflags': [
|
||||
'-O3',
|
||||
],
|
||||
'conditions': [
|
||||
['skia_opencl', {
|
||||
'sources': [
|
||||
'SkCLImageDiffer.cpp',
|
||||
'SkDifferentPixelsMetric_opencl.cpp',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lOpenCL',
|
||||
],
|
||||
},
|
||||
}, {
|
||||
'sources': [
|
||||
'SkDifferentPixelsMetric_cpu.cpp',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:2
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=2 shiftwidth=2:
|
@ -21,6 +21,7 @@
|
||||
'render_pdfs',
|
||||
'render_pictures',
|
||||
'skdiff',
|
||||
'skpdiff',
|
||||
'skhello',
|
||||
'skimage',
|
||||
],
|
||||
@ -50,6 +51,54 @@
|
||||
'skia_lib.gyp:skia_lib',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'skpdiff',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'../tools/skpdiff/skpdiff_main.cpp',
|
||||
'../tools/skpdiff/SkDiffContext.cpp',
|
||||
'../tools/skpdiff/SkImageDiffer.cpp',
|
||||
'../tools/skpdiff/SkPMetric.cpp',
|
||||
'../tools/skpdiff/skpdiff_util.cpp',
|
||||
'../tools/flags/SkCommandLineFlags.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../tools/flags'
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_lib.gyp:skia_lib',
|
||||
],
|
||||
'cflags': [
|
||||
'-O3',
|
||||
],
|
||||
'conditions': [
|
||||
['skia_opencl', {
|
||||
'sources': [
|
||||
'../tools/skpdiff/SkCLImageDiffer.cpp',
|
||||
'../tools/skpdiff/SkDifferentPixelsMetric_opencl.cpp',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'skia_os == "mac"', {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/OpenCL.framework',
|
||||
]
|
||||
}
|
||||
}, {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lOpenCL',
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
}, { # !skia_opencl
|
||||
'sources': [
|
||||
'../tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'skimagediff',
|
||||
'type': 'executable',
|
||||
|
@ -8,7 +8,11 @@
|
||||
#ifndef SkCLImageDiffer_DEFINED
|
||||
#define SkCLImageDiffer_DEFINED
|
||||
|
||||
#include <CL/cl.h>
|
||||
#if SK_BUILD_FOR_MAC
|
||||
# include <OpenCL/cl.h>
|
||||
#else
|
||||
# include <CL/cl.h>
|
||||
#endif
|
||||
#include "SkTDArray.h"
|
||||
|
||||
#include "SkImageDiffer.h"
|
@ -180,7 +180,7 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
||||
stream.writeText("\",\n");
|
||||
|
||||
stream.writeText(" \"result\": ");
|
||||
stream.writeScalarAsText(data.fResult);
|
||||
stream.writeScalarAsText((SkScalar)data.fResult);
|
||||
stream.writeText(",\n");
|
||||
|
||||
stream.writeText(" \"pointsOfInterest\": [\n");
|
@ -22,7 +22,6 @@ static const char kDifferentPixelsKernelSource[] =
|
||||
" int2 coord = (int2)(get_global_id(0), get_global_id(1)); \n"
|
||||
" uint4 baselinePixel = read_imageui(baseline, gInSampler, coord); \n"
|
||||
" uint4 testPixel = read_imageui(test, gInSampler, coord); \n"
|
||||
" int4 pixelCompare = baselinePixel == testPixel; \n"
|
||||
" if (baselinePixel.x != testPixel.x || \n"
|
||||
" baselinePixel.y != testPixel.y || \n"
|
||||
" baselinePixel.z != testPixel.z || \n"
|
||||
@ -120,9 +119,12 @@ int SkDifferentPixelsMetric::queueDiff(SkBitmap* baseline, SkBitmap* test) {
|
||||
diff->result *= (double)diff->numDiffPixels;
|
||||
diff->result = (1.0 - diff->result);
|
||||
|
||||
diff->poi = SkNEW_ARRAY(SkIPoint, diff->numDiffPixels);
|
||||
clEnqueueReadBuffer(fCommandQueue, diff->poiBuffer, CL_TRUE, 0,
|
||||
// Reading a buffer of size zero can cause issues on some (Mac) OpenCL platforms.
|
||||
if (diff->numDiffPixels > 0) {
|
||||
diff->poi = SkNEW_ARRAY(SkIPoint, diff->numDiffPixels);
|
||||
clEnqueueReadBuffer(fCommandQueue, diff->poiBuffer, CL_TRUE, 0,
|
||||
sizeof(SkIPoint) * diff->numDiffPixels, diff->poi, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
// Release all the buffers created
|
||||
clReleaseMemObject(diff->poiBuffer);
|
@ -90,8 +90,7 @@ typedef ImageArray<float> ImageL3D;
|
||||
|
||||
#define MAT_ROW_MULT(rc,gc,bc) r*rc + g*gc + b*bc
|
||||
|
||||
|
||||
void adobergb_to_cielab(float r, float g, float b, LAB* lab) {
|
||||
static void adobergb_to_cielab(float r, float g, float b, LAB* lab) {
|
||||
// Conversion of Adobe RGB to XYZ taken from from "Adobe RGB (1998) ColorImage Encoding"
|
||||
// URL:http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
||||
// Section: 4.3.5.3
|
||||
@ -152,7 +151,7 @@ static void bitmap_to_cielab(const SkBitmap* bitmap, ImageLAB* outImageLAB) {
|
||||
// From Barten SPIE 1989
|
||||
static float contrast_sensitivity(float cyclesPerDegree, float luminance) {
|
||||
float a = 440.0f * powf(1.0f + 0.7f / luminance, -0.2f);
|
||||
float b = 0.3f * powf(1 + 100.0 / luminance, 0.15f);
|
||||
float b = 0.3f * powf(1.0f + 100.0f / luminance, 0.15f);
|
||||
return a *
|
||||
cyclesPerDegree *
|
||||
expf(-b * cyclesPerDegree) *
|
||||
@ -259,14 +258,20 @@ static void convolve(const ImageL* imageL, bool vertical, ImageL* outImageL) {
|
||||
}
|
||||
}
|
||||
|
||||
float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<SkIPoint>* poi) {
|
||||
static double pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<SkIPoint>* poi) {
|
||||
int width = baselineLAB->width;
|
||||
int height = baselineLAB->height;
|
||||
int maxLevels = (int)log2(width < height ? width : height);
|
||||
int maxLevels = 0;
|
||||
|
||||
const float fov = M_PI / 180.0f * 45.0f;
|
||||
// Calculates how many levels to make by how many times the image can be divided in two
|
||||
int smallerDimension = width < height ? width : height;
|
||||
for ( ; smallerDimension > 1; smallerDimension /= 2) {
|
||||
maxLevels++;
|
||||
}
|
||||
|
||||
const float fov = SK_ScalarPI / 180.0f * 45.0f;
|
||||
float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f);
|
||||
float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / M_PI);
|
||||
float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / SK_ScalarPI);
|
||||
|
||||
ImageL3D baselineL(width, height, maxLevels);
|
||||
ImageL3D testL(width, height, maxLevels);
|
||||
@ -326,8 +331,8 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk
|
||||
testL.getLayer(maxLevels - 1)->readPixel(x, y, &avgLTest);
|
||||
|
||||
float lAdapt = 0.5f * (avgLBaseline + avgLTest);
|
||||
if (lAdapt < 1e-5) {
|
||||
lAdapt = 1e-5;
|
||||
if (lAdapt < 1e-5f) {
|
||||
lAdapt = 1e-5f;
|
||||
}
|
||||
|
||||
float contrastSum = 0.0f;
|
||||
@ -352,15 +357,15 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk
|
||||
baselineContrast2 : testContrast2;
|
||||
|
||||
// Avoid divides by close to zero
|
||||
if (denominator < 1e-5) {
|
||||
denominator = 1e-5;
|
||||
if (denominator < 1e-5f) {
|
||||
denominator = 1e-5f;
|
||||
}
|
||||
contrast[levelIndex] = numerator / denominator;
|
||||
contrastSum += contrast[levelIndex];
|
||||
}
|
||||
|
||||
if (contrastSum < 1e-5) {
|
||||
contrastSum = 1e-5;
|
||||
if (contrastSum < 1e-5f) {
|
||||
contrastSum = 1e-5f;
|
||||
}
|
||||
|
||||
float F = 0.0f;
|
@ -179,7 +179,7 @@ static float gCubeRootTable[] = {
|
||||
0.9967341374f,0.9970616873f,0.9973890221f,0.9977161421f,0.9980430478f,0.9983697395f,
|
||||
0.9986962176f,0.9990224823f,0.9993485340f,0.9996743731f,
|
||||
};
|
||||
float get_cube_root(float value) {
|
||||
static float get_cube_root(float value) {
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value * 1023.0f < 1024.0f);
|
||||
return gCubeRootTable[(int)(value * 1023.0f)];
|
||||
@ -230,7 +230,7 @@ static float gGammaTable[] = {
|
||||
0.9239933353f,0.9322768503f,0.9406007070f,0.9489649382f,0.9573695762f,0.9658146535f,
|
||||
0.9743002024f,0.9828262551f,0.9913928436f,1.0000000000f,
|
||||
};
|
||||
float get_gamma(unsigned char value) {
|
||||
static float get_gamma(unsigned char value) {
|
||||
return gGammaTable[value];
|
||||
}
|
||||
|
||||
@ -1903,7 +1903,7 @@ static float gTVITable[] = {
|
||||
5.5534835301f,5.5540394344f,5.5545953386f,5.5551512429f,5.5557071472f,5.5562630514f,
|
||||
5.5568189557f,5.5573748599f,5.5579307642f,5.5584866684f,
|
||||
};
|
||||
float get_threshold_vs_intensity(float value) {
|
||||
static float get_threshold_vs_intensity(float value) {
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value < 100.0f);
|
||||
return gTVITable[(int)(value * 100.0f)];
|
||||
@ -2578,7 +2578,7 @@ static float gVisualMaskTable[] = {
|
||||
331.9392982234f,331.9975309989f,332.0557593973f,332.1139834200f,332.1722030684f,332.2304183439f,
|
||||
332.2886292480f,332.3468357821f,332.4050379475f,332.4632357458f,
|
||||
};
|
||||
float get_visual_mask(float value) {
|
||||
static float get_visual_mask(float value) {
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value < 4000.0f);
|
||||
return gVisualMaskTable[(int)value];
|
@ -60,7 +60,7 @@ def visual_mask(contrast):
|
||||
|
||||
# float gCubeRootTable[]
|
||||
CUBE_ROOT_ACCESS_FUNCTION = '''
|
||||
float get_cube_root(float value) {
|
||||
static float get_cube_root(float value) {
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value * 1023.0f < 1024.0f);
|
||||
return gCubeRootTable[(int)(value * 1023.0f)];
|
||||
@ -78,7 +78,7 @@ def generate_cube_root_table(stream):
|
||||
|
||||
# float gGammaTable[]
|
||||
GAMMA_ACCESS_FUNCTION = '''
|
||||
float get_gamma(unsigned char value) {
|
||||
static float get_gamma(unsigned char value) {
|
||||
return gGammaTable[value];
|
||||
}
|
||||
'''
|
||||
@ -94,7 +94,7 @@ def generate_gamma_table(stream):
|
||||
|
||||
# float gTVITable[]
|
||||
TVI_ACCESS_FUNCTION = '''
|
||||
float get_threshold_vs_intensity(float value) {
|
||||
static float get_threshold_vs_intensity(float value) {
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value < 100.0f);
|
||||
return gTVITable[(int)(value * 100.0f)];
|
||||
@ -113,7 +113,7 @@ def generate_tvi_table(stream):
|
||||
# float gVisualMaskTable[]
|
||||
VISUAL_MASK_DOMAIN = 4000
|
||||
VISUAL_MASK_ACCESS_FUNCTION = '''
|
||||
float get_visual_mask(float value) {{
|
||||
static float get_visual_mask(float value) {{
|
||||
SkASSERT(value >= 0.0f);
|
||||
SkASSERT(value < {}.0f);
|
||||
return gVisualMaskTable[(int)value];
|
@ -6,9 +6,16 @@
|
||||
*/
|
||||
|
||||
#if SK_SUPPORT_OPENCL
|
||||
|
||||
#define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr
|
||||
#define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string
|
||||
#include <CL/cl.hpp>
|
||||
#if SK_BUILD_FOR_MAC
|
||||
// Note that some macs don't have this header and it can be downloaded from the Khronos registry
|
||||
# include <OpenCL/cl.hpp>
|
||||
#else
|
||||
# include <CL/cl.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "SkCommandLineFlags.h"
|
||||
@ -35,7 +42,7 @@ DEFINE_bool(jsonp, true, "Output JSON with padding");
|
||||
|
||||
#if SK_SUPPORT_OPENCL
|
||||
/// A callback for any OpenCL errors
|
||||
CL_CALLBACK void error_notify(const char* errorInfo, const void* privateInfoSize, ::size_t cb, void* userData) {
|
||||
static void CL_CALLBACK error_notify(const char* errorInfo, const void* privateInfoSize, ::size_t cb, void* userData) {
|
||||
SkDebugf("OpenCL error notify: %s\n", errorInfo);
|
||||
exit(1);
|
||||
}
|
||||
@ -55,8 +62,8 @@ static bool init_device_and_context(cl::Device* device, cl::Context* context) {
|
||||
|
||||
// Query for a device
|
||||
cl::vector<cl::Device> deviceList;
|
||||
platform.getDevices(CL_DEVICE_TYPE_GPU, &deviceList);
|
||||
SkDebugf("The number of GPU devices is %u\n", deviceList.size());
|
||||
platform.getDevices(CL_DEVICE_TYPE_ALL, &deviceList);
|
||||
SkDebugf("The number of devices is %u\n", deviceList.size());
|
||||
|
||||
// Print some information about the device for debugging
|
||||
*device = deviceList[0];
|
@ -5,9 +5,16 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <glob.h>
|
||||
#if SK_BUILD_FOR_MAC || SK_BUILD_FOR_UNIX
|
||||
# include <unistd.h>
|
||||
# include <time.h>
|
||||
# include <sys/time.h>
|
||||
# include <dirent.h>
|
||||
# include <glob.h>
|
||||
#elif SK_BUILD_FOR_WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "SkOSFile.h"
|
||||
#include "skpdiff_util.h"
|
||||
|
||||
@ -66,14 +73,27 @@ const char* cl_error_to_string(cl_int err) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TODO refactor BenchTimer to be used here
|
||||
double get_seconds() {
|
||||
#if defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)
|
||||
struct timespec currentTime;
|
||||
clock_gettime(CLOCK_REALTIME, ¤tTime);
|
||||
return currentTime.tv_sec + (double)currentTime.tv_nsec / 1e9;
|
||||
#elif SK_BUILD_FOR_MAC || SK_BUILD_FOR_UNIX
|
||||
struct timeval currentTime;
|
||||
gettimeofday(¤tTime, NULL);
|
||||
return currentTime.tv_sec + (double)currentTime.tv_usec / 1e6;
|
||||
#elif SK_BUILD_FOR_WIN32
|
||||
LARGE_INTEGER currentTime;
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return (double)currentTime.QuadPart / (double)frequency.QuadPart;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool get_directory(const char path[], SkTArray<SkString>* entries) {
|
||||
#if SK_BUILD_FOR_MAC || SK_BUILD_FOR_UNIX
|
||||
// Open the directory and check for success
|
||||
DIR* dir = opendir(path);
|
||||
if (NULL == dir) {
|
||||
@ -96,9 +116,41 @@ bool get_directory(const char path[], SkTArray<SkString>* entries) {
|
||||
closedir(dir);
|
||||
|
||||
return true;
|
||||
#elif SK_BUILD_FOR_WIN32
|
||||
char pathDirGlob[MAX_PATH];
|
||||
char pathLength = strlen(path);
|
||||
strncpy(pathDirGlob, path, pathLength);
|
||||
|
||||
if (path[pathLength - 1] == '/' || path[pathLength - 1] == '\\') {
|
||||
SkASSERT(pathLength + 2 <= MAX_PATH);
|
||||
pathDirGlob[pathLength] = '*';
|
||||
pathDirGlob[pathLength + 1] = '\0';
|
||||
} else {
|
||||
SkASSERT(pathLength + 3 <= MAX_PATH);
|
||||
pathDirGlob[pathLength] = '\\';
|
||||
pathDirGlob[pathLength + 1] = '*';
|
||||
pathDirGlob[pathLength + 2] = '\0';
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA findFileData;
|
||||
HANDLE hFind = FindFirstFile(pathDirGlob, &findFileData);
|
||||
if (INVALID_HANDLE_VALUE == hFind) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if ((findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
entries->push_back(SkString(findFileData.cFileName));
|
||||
}
|
||||
} while (FindNextFile(hFind, &findFileData) != 0);
|
||||
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool glob_files(const char globPattern[], SkTArray<SkString>* entries) {
|
||||
#if SK_BUILD_FOR_MAC || SK_BUILD_FOR_UNIX
|
||||
// TODO Make sure this works on windows. This may require use of FindNextFile windows function.
|
||||
glob_t globBuffer;
|
||||
if (glob(globPattern, 0, NULL, &globBuffer) != 0) {
|
||||
@ -116,4 +168,7 @@ bool glob_files(const char globPattern[], SkTArray<SkString>* entries) {
|
||||
globfree(&globBuffer);
|
||||
|
||||
return true;
|
||||
#elif SK_BUILD_FOR_WIN32
|
||||
return false;
|
||||
#endif
|
||||
}
|
@ -12,7 +12,12 @@
|
||||
#include "SkTArray.h"
|
||||
|
||||
#if SK_SUPPORT_OPENCL
|
||||
#include <CL/cl.h>
|
||||
#if SK_BUILD_FOR_MAC
|
||||
# include <OpenCL/cl.h>
|
||||
#else
|
||||
# include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Converts an OpenCL error number into the string of its enumeration name.
|
||||
* @param err The OpenCL error number
|
@ -60,4 +60,4 @@
|
||||
<!-- Whatever template is used is rendered in the following div -->
|
||||
<div ng-view></div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user