Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: experimental/skpdiff/SkDifferentPixelsMetric_opencl.cpp

Issue 19374006: make OpenCL optional for skpdiff (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBitmap.h"
9
10 #include "SkDifferentPixelsMetric.h"
11 #include "skpdiff_util.h"
12
13 struct SkDifferentPixelsMetric::QueuedDiff {
14 bool finished;
15 double result;
16 int numDiffPixels;
17 SkIPoint* poi;
18 cl_mem baseline;
19 cl_mem test;
20 cl_mem resultsBuffer;
21 cl_mem poiBuffer;
22 };
23
24 const char* SkDifferentPixelsMetric::getName() {
25 return "different_pixels";
26 }
27
28 int SkDifferentPixelsMetric::queueDiff(SkBitmap* baseline, SkBitmap* test) {
29 int diffID = fQueuedDiffs.count();
30 double startTime = get_seconds();
31 QueuedDiff* diff = fQueuedDiffs.push();
32
33 // If we never end up running the kernel, include some safe defaults in the result.
34 diff->finished = false;
35 diff->result = -1.0;
36 diff->numDiffPixels = 0;
37 diff->poi = NULL;
38
39 // Ensure the images are comparable
40 if (baseline->width() != test->width() || baseline->height() != test->height () ||
41 baseline->width() <= 0 || baseline->height() <= 0 ||
42 baseline->config() != test->config()) {
43 diff->finished = true;
44 return diffID;
45 }
46
47 // Upload images to the CL device
48 if (!this->makeImage2D(baseline, &diff->baseline) || !this->makeImage2D(test , &diff->test)) {
49 diff->finished = true;
50 fIsGood = false;
51 return -1;
52 }
53
54 // A small hack that makes calculating percentage difference easier later on .
55 diff->result = 1.0 / ((double)baseline->width() * baseline->height());
56
57 // Make a buffer to store results into. It must be initialized with pointers to memory.
58 static const int kZero = 0;
59 // We know OpenCL won't write to it because we use CL_MEM_COPY_HOST_PTR
60 diff->resultsBuffer = clCreateBuffer(fContext, CL_MEM_READ_WRITE | CL_MEM_CO PY_HOST_PTR,
61 sizeof(int), (int*)&kZero, NULL);
62
63 diff->poiBuffer = clCreateBuffer(fContext, CL_MEM_WRITE_ONLY,
64 sizeof(int) * 2 * baseline->width() * basel ine->height(),
65 NULL, NULL);
66
67 // Set all kernel arguments
68 cl_int setArgErr = clSetKernelArg(fKernel, 0, sizeof(cl_mem), &diff->baselin e);
69 setArgErr |= clSetKernelArg(fKernel, 1, sizeof(cl_mem), &diff->test);
70 setArgErr |= clSetKernelArg(fKernel, 2, sizeof(cl_mem), &diff->results Buffer);
71 setArgErr |= clSetKernelArg(fKernel, 3, sizeof(cl_mem), &diff->poiBuff er);
72 if (CL_SUCCESS != setArgErr) {
73 SkDebugf("Set arg failed: %s\n", cl_error_to_string(setArgErr));
74 fIsGood = false;
75 return -1;
76 }
77
78 // Queue this diff on the CL device
79 cl_event event;
80 const size_t workSize[] = { baseline->width(), baseline->height() };
81 cl_int enqueueErr;
82 enqueueErr = clEnqueueNDRangeKernel(fCommandQueue, fKernel, 2, NULL, workSiz e,
83 NULL, 0, NULL, &event);
84 if (CL_SUCCESS != enqueueErr) {
85 SkDebugf("Enqueue failed: %s\n", cl_error_to_string(enqueueErr));
86 fIsGood = false;
87 return -1;
88 }
89
90 // This makes things totally synchronous. Actual queue is not ready yet
91 clWaitForEvents(1, &event);
92 diff->finished = true;
93
94 // Immediate read back the results
95 clEnqueueReadBuffer(fCommandQueue, diff->resultsBuffer, CL_TRUE, 0,
96 sizeof(int), &diff->numDiffPixels, 0, NULL, NULL);
97 diff->result *= (double)diff->numDiffPixels;
98 diff->result = (1.0 - diff->result);
99
100 diff->poi = SkNEW_ARRAY(SkIPoint, diff->numDiffPixels);
101 clEnqueueReadBuffer(fCommandQueue, diff->poiBuffer, CL_TRUE, 0,
102 sizeof(SkIPoint) * diff->numDiffPixels, diff->poi, 0, NU LL, NULL);
103
104 // Release all the buffers created
105 clReleaseMemObject(diff->poiBuffer);
106 clReleaseMemObject(diff->resultsBuffer);
107 clReleaseMemObject(diff->baseline);
108 clReleaseMemObject(diff->test);
109
110 SkDebugf("Time: %f\n", (get_seconds() - startTime));
111
112 return diffID;
113 }
114
115 void SkDifferentPixelsMetric::deleteDiff(int id) {
116 QueuedDiff* diff = &fQueuedDiffs[id];
117 if (NULL != diff->poi) {
118 SkDELETE_ARRAY(diff->poi);
119 diff->poi = NULL;
120 }
121 }
122
123 bool SkDifferentPixelsMetric::isFinished(int id) {
124 return fQueuedDiffs[id].finished;
125 }
126
127 double SkDifferentPixelsMetric::getResult(int id) {
128 return fQueuedDiffs[id].result;
129 }
130
131 int SkDifferentPixelsMetric::getPointsOfInterestCount(int id) {
132 return fQueuedDiffs[id].numDiffPixels;
133 }
134
135 SkIPoint* SkDifferentPixelsMetric::getPointsOfInterest(int id) {
136 return fQueuedDiffs[id].poi;
137 }
138
139 bool SkDifferentPixelsMetric::onInit() {
140 if (!loadKernelFile("experimental/skpdiff/diff_pixels.cl", "diff", &fKernel) ) {
141 return false;
142 }
143
144 return true;
145 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698