Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2014 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 "Test.h"
      9 
     10 #include "SkBitmap.h"
     11 #include "SkImageInfo.h"
     12 #include "SkShader.h"
     13 #include "SkRecord.h"
     14 #include "SkRecords.h"
     15 
     16 // Sums the area of any DrawRect command it sees.
     17 class AreaSummer {
     18 public:
     19     AreaSummer() : fArea(0) {}
     20 
     21     template <typename T> void operator()(const T&) { }
     22 
     23     void operator()(const SkRecords::DrawRect& draw) {
     24         fArea += (int)(draw.rect.width() * draw.rect.height());
     25     }
     26 
     27     int area() const { return fArea; }
     28 
     29     void apply(const SkRecord& record) {
     30         for (unsigned i = 0; i < record.count(); i++) {
     31             record.visit<void>(i, *this);
     32         }
     33     }
     34 
     35 private:
     36     int fArea;
     37 };
     38 
     39 // Scales out the bottom-right corner of any DrawRect command it sees by 2x.
     40 struct Stretch {
     41     template <typename T> void operator()(T*) {}
     42     void operator()(SkRecords::DrawRect* draw) {
     43         draw->rect.fRight *= 2;
     44         draw->rect.fBottom *= 2;
     45     }
     46 
     47     void apply(SkRecord* record) {
     48         for (unsigned i = 0; i < record->count(); i++) {
     49             record->mutate<void>(i, *this);
     50         }
     51     }
     52 };
     53 
     54 #define APPEND(record, type, ...) SkNEW_PLACEMENT_ARGS(record.append<type>(), type, (__VA_ARGS__))
     55 
     56 // Basic tests for the low-level SkRecord code.
     57 DEF_TEST(Record, r) {
     58     SkRecord record;
     59 
     60     // Add a simple DrawRect command.
     61     SkRect rect = SkRect::MakeWH(10, 10);
     62     SkPaint paint;
     63     APPEND(record, SkRecords::DrawRect, paint, rect);
     64 
     65     // Its area should be 100.
     66     AreaSummer summer;
     67     summer.apply(record);
     68     REPORTER_ASSERT(r, summer.area() == 100);
     69 
     70     // Scale 2x.
     71     Stretch stretch;
     72     stretch.apply(&record);
     73 
     74     // Now its area should be 100 + 400.
     75     summer.apply(record);
     76     REPORTER_ASSERT(r, summer.area() == 500);
     77 }
     78 
     79 #undef APPEND
     80 
     81 template <typename T>
     82 static bool is_aligned(const T* p) {
     83     return (((uintptr_t)p) & (sizeof(T) - 1)) == 0;
     84 }
     85 
     86 DEF_TEST(Record_Alignment, r) {
     87     SkRecord record;
     88 
     89     // Of course a byte's always aligned.
     90     REPORTER_ASSERT(r, is_aligned(record.alloc<uint8_t>()));
     91 
     92     // (If packed tightly, the rest below here would be off by one.)
     93 
     94     // It happens that the first implementation always aligned to 4 bytes,
     95     // so these two were always correct.
     96     REPORTER_ASSERT(r, is_aligned(record.alloc<uint16_t>()));
     97     REPORTER_ASSERT(r, is_aligned(record.alloc<uint32_t>()));
     98 
     99     // These two are regression tests (void* only on 64-bit machines).
    100     REPORTER_ASSERT(r, is_aligned(record.alloc<uint64_t>()));
    101     REPORTER_ASSERT(r, is_aligned(record.alloc<void*>()));
    102 
    103     // We're not testing beyond sizeof(void*), which is where the current implementation will break.
    104 }
    105 
    106