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#ifndef SkCLImageDiffer_DEFINED
9#define SkCLImageDiffer_DEFINED
10
11#if defined(SK_BUILD_FOR_MAC)
12#   include <OpenCL/cl.h>
13#else
14#   include <CL/cl.h>
15#endif
16#include "SkTDArray.h"
17
18#include "SkImageDiffer.h"
19
20class SkStream;
21
22/**
23 * An SkImageDiffer that requires initialization with an OpenCL device and context.
24 */
25class SkCLImageDiffer : public SkImageDiffer {
26public:
27    SkCLImageDiffer();
28
29    bool requiresOpenCL() const override { return true; }
30
31    /**
32     * Initializes the OpenCL resources this differ needs to work
33     * @param  device  An OpenCL device
34     * @param  context An OpenCL context of the given device
35     * @return         True on success, false otherwise
36     */
37    virtual bool init(cl_device_id device, cl_context context);
38
39protected:
40    /**
41     * Called by init after fDevice, fContext, and fCommandQueue are successfully initialized
42     * @return True on success, false otherwise
43     */
44    virtual bool onInit() = 0;
45
46    /**
47     * Loads an OpenCL kernel from the file with the given named entry point. This only works after
48     * init is called.
49     * @param  file   The file path of the kernel
50     * @param  name   The name of the entry point of the desired kernel in the file
51     * @param  kernel A pointer to return the loaded kernel into
52     * @return        True on success, false otherwise
53     */
54    bool loadKernelFile(const char file[], const char name[], cl_kernel* kernel);
55
56    /**
57     * Loads an OpenCL kernel from the stream with the given named entry point. This only works
58     * after init is called.
59     * @param  stream  The stream that contains the kernel
60     * @param  name    The name of the entry point of the desired kernel in the stream
61     * @param  kernel  A pointer to return the loaded kernel into
62     * @return         True on success, false otherwise
63     */
64    bool loadKernelStream(SkStream* stream, const char name[], cl_kernel* kernel);
65
66    /**
67     * Loads an OpenCL kernel from the source string with the given named entry point. This only
68     * works after init is called.
69     * @param  source  The string that contains the kernel
70     * @param  name    The name of the entry point of the desired kernel in the source string
71     * @param  kernel  A pointer to return the loaded kernel into
72     * @return         True on success, false otherwise
73     */
74    bool loadKernelSource(const char source[], const char name[], cl_kernel* kernel);
75
76    /**
77     * Loads a read only copy of the given bitmap into device memory and returns the block of
78     * memory. This only works after init is called.
79     * @param  bitmap The bitmap to load into memory
80     * @param  image  A pointer to return the allocated image to
81     * @return        True on success, false otherwise
82     */
83    bool makeImage2D(SkBitmap* bitmap, cl_mem* image) const;
84
85    cl_device_id     fDevice;
86    cl_context       fContext;
87    cl_command_queue fCommandQueue;
88
89protected:
90    bool fIsGood;
91
92private:
93
94    typedef SkImageDiffer INHERITED;
95};
96
97#endif
98