1be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org/* 2be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org * Copyright 2013 Google Inc. 3be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org * 4be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org * found in the LICENSE file. 6be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org */ 7be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 8be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org#include <cstring> 9be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 10be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org#include "SkBitmap.h" 11be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org#include "SkStream.h" 12be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 13be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org#include "SkCLImageDiffer.h" 14be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org#include "skpdiff_util.h" 15be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 16be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.orgSkCLImageDiffer::SkCLImageDiffer() { 17be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fIsGood = false; 18be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 19be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 20be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.orgbool SkCLImageDiffer::init(cl_device_id device, cl_context context) { 21be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fContext = context; 22be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fDevice = device; 23be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 24be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_int queueErr; 25be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fCommandQueue = clCreateCommandQueue(fContext, fDevice, 0, &queueErr); 26be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (CL_SUCCESS != queueErr) { 27be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Command queue creation failed: %s\n", cl_error_to_string(queueErr)); 28be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fIsGood = false; 29be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 30be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 31be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 32be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org fIsGood = this->onInit(); 33be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return fIsGood; 34be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 35be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 36be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.orgbool SkCLImageDiffer::loadKernelFile(const char file[], const char name[], cl_kernel* kernel) { 37be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org // Open the kernel source file 38be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkFILEStream sourceStream(file); 39be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (!sourceStream.isValid()) { 40be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Failed to open kernel source file"); 41be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 42be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 43be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 44be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return loadKernelStream(&sourceStream, name, kernel); 45be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 46be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 47be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.orgbool SkCLImageDiffer::loadKernelStream(SkStream* stream, const char name[], cl_kernel* kernel) { 48be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org // Read the kernel source into memory 49be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkString sourceString; 50be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org sourceString.resize(stream->getLength()); 51be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org size_t bytesRead = stream->read(sourceString.writable_str(), sourceString.size()); 52be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (bytesRead != sourceString.size()) { 53be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Failed to read kernel source file"); 54be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 55be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 56be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 57be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return loadKernelSource(sourceString.c_str(), name, kernel); 58be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 59be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 60be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.orgbool SkCLImageDiffer::loadKernelSource(const char source[], const char name[], cl_kernel* kernel) { 61be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org // Build the kernel source 62be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org size_t sourceLen = strlen(source); 63be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_program program = clCreateProgramWithSource(fContext, 1, &source, &sourceLen, NULL); 64be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_int programErr = clBuildProgram(program, 1, &fDevice, "", NULL, NULL); 65be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (CL_SUCCESS != programErr) { 66be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Program creation failed: %s\n", cl_error_to_string(programErr)); 67be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 68be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org // Attempt to get information about why the build failed 69be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org char buildLog[4096]; 70572b54dd7afdbe12d874ad9d2a82fc75485fae87zachr@google.com clGetProgramBuildInfo(program, fDevice, CL_PROGRAM_BUILD_LOG, sizeof(buildLog), 71572b54dd7afdbe12d874ad9d2a82fc75485fae87zachr@google.com buildLog, NULL); 72be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Build log: %s\n", buildLog); 73be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 74be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 75be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 76be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 77be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_int kernelErr; 78be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org *kernel = clCreateKernel(program, name, &kernelErr); 79be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (CL_SUCCESS != kernelErr) { 80be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Kernel creation failed: %s\n", cl_error_to_string(kernelErr)); 81be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 82be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 83be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 84be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return true; 85be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 86be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 87efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.combool SkCLImageDiffer::makeImage2D(SkBitmap* bitmap, cl_mem* image) const { 88be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_int imageErr; 89be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org cl_image_format bitmapFormat; 900689d7b12e7c427a077b003d3d8ae759d86f798freed switch (bitmap->colorType()) { 910689d7b12e7c427a077b003d3d8ae759d86f798freed case kAlpha_8_SkColorType: 92be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_order = CL_A; 93be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_data_type = CL_UNSIGNED_INT8; 94be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org break; 950689d7b12e7c427a077b003d3d8ae759d86f798freed case kRGB_565_SkColorType: 96be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_order = CL_RGB; 97be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_data_type = CL_UNORM_SHORT_565; 98be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org break; 990689d7b12e7c427a077b003d3d8ae759d86f798freed case kN32_SkColorType: 100be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_order = CL_RGBA; 101be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmapFormat.image_channel_data_type = CL_UNSIGNED_INT8; 102be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org break; 103be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org default: 104be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Image format is unsupported\n"); 105be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 106be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 107be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 108be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org // Upload the bitmap data to OpenCL 109be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmap->lockPixels(); 110be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org *image = clCreateImage2D(fContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 111be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org &bitmapFormat, bitmap->width(), bitmap->height(), 112be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmap->rowBytes(), bitmap->getPixels(), 113be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org &imageErr); 114be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org bitmap->unlockPixels(); 115be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 116be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org if (CL_SUCCESS != imageErr) { 117be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org SkDebugf("Input image creation failed: %s\n", cl_error_to_string(imageErr)); 118be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return false; 119be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org } 120be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org 121be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org return true; 122be19b9ef9a46df7d7308f273f6f7efa905cc7d72commit-bot@chromium.org} 123