1bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl
2adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell/*
3adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell * Copyright 2014 Google Inc.
4adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell *
5adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell * Use of this source code is governed by a BSD-style license that can be
6adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell * found in the LICENSE file.
7adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell */
8adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
9adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell// This test only works with the GPU backend.
10adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
11adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "gm.h"
12adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
13adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#if SK_SUPPORT_GPU
14adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
15adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "GrContext.h"
16adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "GrTest.h"
17adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "effects/GrYUVtoRGBEffect.h"
18adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "SkBitmap.h"
19adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "SkGr.h"
20adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#include "SkGradientShader.h"
21adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
22adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwellnamespace skiagm {
23adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell/**
24adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell * This GM directly exercises GrYUVtoRGBEffect.
25adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell */
26adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwellclass YUVtoRGBEffect : public GM {
27adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwellpublic:
28adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    YUVtoRGBEffect() {
29adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        this->setBGColor(0xFFFFFFFF);
30adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    }
31adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
32adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwellprotected:
33adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    virtual SkString onShortName() SK_OVERRIDE {
34adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        return SkString("yuv_to_rgb_effect");
35adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    }
36adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
37adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    virtual SkISize onISize() SK_OVERRIDE {
38e946688edac5cdf153652defae3ef732a3487416Ian Romanick        return SkISize::Make(334, 128);
39ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl    }
40ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl
41adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    virtual uint32_t onGetFlags() const SK_OVERRIDE {
42adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        // This is a GPU-specific GM.
43ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul        return kGPUOnly_Flag;
44ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul    }
45ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul
46adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    virtual void onOnceBeforeDraw() SK_OVERRIDE {
4798c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        SkImageInfo info = SkImageInfo::MakeA8(24, 24);
48adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        fBmp[0].allocPixels(info);
49bf35d70635309e499aee666eb5811446aa8b489eRoland Scheidegger        fBmp[1].allocPixels(info);
50bf35d70635309e499aee666eb5811446aa8b489eRoland Scheidegger        fBmp[2].allocPixels(info);
51bf35d70635309e499aee666eb5811446aa8b489eRoland Scheidegger        unsigned char* pixels[3];
52bf35d70635309e499aee666eb5811446aa8b489eRoland Scheidegger        for (int i = 0; i < 3; ++i) {
534637235183b80963536f2364e4d50fcb894886ddDave Airlie            pixels[i] = (unsigned char*)fBmp[i].getPixels();
548cb16e6daff40bbfd7b63a43da72862226a4a164Dave Airlie        }
558cb16e6daff40bbfd7b63a43da72862226a4a164Dave Airlie        int color[] = {0, 85, 170};
56adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        const int limit[] = {255, 0, 255};
57adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        const int invl[]  = {0, 255, 0};
58adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        const int inc[]   = {1, -1, 1};
59adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        for (int j = 0; j < 576; ++j) {
604637235183b80963536f2364e4d50fcb894886ddDave Airlie            for (int i = 0; i < 3; ++i) {
61adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                pixels[i][j] = (unsigned char)color[i];
6298c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger                color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
63122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul            }
6498c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        }
65fc606f7db9072d4f40081aea8f92f1d4489a5115Roland Scheidegger    }
66fc606f7db9072d4f40081aea8f92f1d4489a5115Roland Scheidegger
67fc606f7db9072d4f40081aea8f92f1d4489a5115Roland Scheidegger    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
6898c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
6998c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        if (NULL == rt) {
70421ce180f52ff55b866066fabd861a51dd6d2b26Roland Scheidegger            return;
7198c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        }
72fc606f7db9072d4f40081aea8f92f1d4489a5115Roland Scheidegger        GrContext* context = rt->getContext();
73fc606f7db9072d4f40081aea8f92f1d4489a5115Roland Scheidegger        if (NULL == context) {
7498c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger            return;
7598c791b543c4ba86b8bb54488bd872b33b10b1aaRoland Scheidegger        }
76692ca82116485a9c6191e5265c5b369d5b4f82f3Dave Airlie
77adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrTestTarget tt;
78adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        context->getTestTarget(&tt);
79adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        if (NULL == tt.target()) {
80692ca82116485a9c6191e5265c5b369d5b4f82f3Dave Airlie            SkDEBUGFAIL("Couldn't get Gr test target.");
8136603539ccdb1c507724d8a1c314e6c9cc9863d9Roland Scheidegger            return;
8236603539ccdb1c507724d8a1c314e6c9cc9863d9Roland Scheidegger        }
83adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
84adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrDrawState* drawState = tt.target()->drawState();
8548ccaf200940613032dfaaafe71382947f398004Roland Scheidegger
86adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrTexture* texture[3];
87adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        texture[0] = GrLockAndRefCachedBitmapTexture(context, fBmp[0], NULL);
88adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        texture[1] = GrLockAndRefCachedBitmapTexture(context, fBmp[1], NULL);
89adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        texture[2] = GrLockAndRefCachedBitmapTexture(context, fBmp[2], NULL);
90adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        if ((NULL == texture[0]) || (NULL == texture[1]) || (NULL == texture[2])) {
91adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell            return;
92adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        }
93adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
94adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        static const SkScalar kDrawPad = 10.f;
95adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        static const SkScalar kTestPad = 10.f;
96adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        static const SkScalar kColorSpaceOffset = 64.f;
97adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
98adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
99adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell             ++space) {
100adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
101adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                                             SkIntToScalar(fBmp[0].height()));
102adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          renderRect.outset(kDrawPad, kDrawPad);
103adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
104adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
105adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          SkScalar x = kDrawPad + kTestPad;
106adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
107adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
108adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
109adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          for (int i = 0; i < 6; ++i) {
110adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell              SkAutoTUnref<GrFragmentProcessor> fp(
111adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                          GrYUVtoRGBEffect::Create(texture[indices[i][0]],
112033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger                                                   texture[indices[i][1]],
113033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger                                                   texture[indices[i][2]],
114033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger                                                   static_cast<SkYUVColorSpace>(space)));
115033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger              if (fp) {
116033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger                  SkMatrix viewMatrix;
117033728555cb2f39d8c77f228e1eccc45329bb40aRoland Scheidegger                  viewMatrix.setTranslate(x, y);
118adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                  drawState->reset(viewMatrix);
119adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                  drawState->setRenderTarget(rt);
120adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                  drawState->setColor(0xffffffff);
121adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                  drawState->addColorProcessor(fp);
122adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell                  tt.target()->drawSimpleRect(renderRect);
123adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell              }
124adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell              x += renderRect.width() + kTestPad;
125adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell          }
126adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        }
127adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
128adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrUnlockAndUnrefCachedBitmapTexture(texture[0]);
129adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrUnlockAndUnrefCachedBitmapTexture(texture[1]);
130adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell        GrUnlockAndUnrefCachedBitmapTexture(texture[2]);
131adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    }
132adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
133adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwellprivate:
134adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    SkBitmap fBmp[3];
135adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
136adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell    typedef GM INHERITED;
137adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell};
138adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
139adbec39bbf671ad80f6c557801e274cac0d305faKeith WhitwellDEF_GM( return SkNEW(YUVtoRGBEffect); )
140adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell}
141adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell
142adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell#endif
143adbec39bbf671ad80f6c557801e274cac0d305faKeith Whitwell