Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Whole-tree processing that's likely to be helpful in multiple render models. | |
| 6 | |
| 7 #include "gpu/tools/compositor_model_bench/render_model_utils.h" | |
| 8 | |
| 9 #include <cstdlib> | |
| 10 #include <map> | |
| 11 #include <set> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/logging.h" | |
| 15 | |
| 16 TextureGenerator::TextureGenerator(RenderNode* root) | |
| 17 : stage_(DiscoveryStage), | |
| 18 tex_ids_(NULL), | |
| 19 image_data_(NULL), | |
| 20 images_generated_(0) { | |
| 21 DiscoverInputIDs(root); | |
| 22 GenerateGLTexIDs(); | |
| 23 AssignIDMapping(); | |
| 24 WriteOutNewIDs(root); | |
| 25 AllocateImageArray(); | |
| 26 BuildTextureImages(root); | |
| 27 } | |
| 28 | |
| 29 TextureGenerator::~TextureGenerator() OVERRIDE { | |
| 30 if (tex_ids_.get()) { | |
| 31 glDeleteTextures(discovered_ids_.size(), tex_ids_.get()); | |
| 32 } | |
| 33 } | |
| 34 | |
| 35 void TextureGenerator::BeginVisitRenderNode(RenderNode* node) OVERRIDE { | |
| 36 typedef std::vector<Tile>::iterator tile_itr; | |
| 37 for (tile_itr i = node->tiles.begin(); i != node->tiles.end(); ++i) { | |
| 38 HandleTexture(&i->texID, | |
| 39 node->tile_width, | |
|
piman
2011/08/26 02:24:16
nit: indentation (align arguments)
| |
| 40 node->tile_height, | |
| 41 GL_RGBA); | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 void TextureGenerator::BeginVisitCCNode(CCNode* node) OVERRIDE { | |
| 46 typedef std::vector<Texture>::iterator tex_itr; | |
| 47 for (tex_itr i = node->textures.begin(); i != node->textures.end(); ++i) { | |
| 48 HandleTexture(&i->texID, i->width, i->height, i->format); | |
| 49 } | |
| 50 BeginVisitRenderNode(node); | |
| 51 } | |
| 52 | |
| 53 void TextureGenerator::DiscoverInputIDs(RenderNode* root) { | |
| 54 // Pass 1: see which texture ID's have been used. | |
| 55 stage_ = DiscoveryStage; | |
| 56 root->Accept(this); | |
| 57 } | |
| 58 | |
| 59 void TextureGenerator::GenerateGLTexIDs() { | |
| 60 int numTextures = discovered_ids_.size(); | |
| 61 tex_ids_.reset(new GLuint[numTextures]); | |
| 62 glGenTextures(numTextures, tex_ids_.get()); | |
| 63 } | |
| 64 | |
| 65 void TextureGenerator::AssignIDMapping() { | |
| 66 // In the original version of this code the assigned ID's were not | |
| 67 // GL tex ID's, but newly generated consecutive ID's that indexed | |
| 68 // into an array of GL tex ID's. There's no need for this and now | |
| 69 // I'm instead generating the GL tex ID's upfront and assigning | |
| 70 // *those* in the remapping -- this more accurately reflects the | |
| 71 // behavior in Chromium, and it also takes out some design | |
| 72 // complexity that came from the extra layer of indirection. | |
| 73 // HOWEVER -- when I was assigning my own ID's before, I did some | |
| 74 // clever tricks to make sure the assignation was idempotent. | |
| 75 // Instead of going to even more clever lengths to preserve that | |
| 76 // property, I now just assume that the visitor will encounter each | |
| 77 // node (and consequently each texture) exactly once during a | |
| 78 // traversal of the tree -- this shouldn't be a hard guarantee | |
| 79 // to make. | |
| 80 int j = 0; | |
| 81 typedef std::set<int>::iterator id_itr; | |
| 82 for (id_itr i = discovered_ids_.begin(); | |
| 83 i != discovered_ids_.end(); | |
|
piman
2011/08/26 02:24:16
nit: indentation (align all 3 statements)
| |
| 84 ++i, ++j) { | |
| 85 remapped_ids_[*i] = tex_ids_[j]; | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 void TextureGenerator::WriteOutNewIDs(RenderNode* root) { | |
| 90 // Pass 2: write the new texture ID's back into the texture objects. | |
| 91 stage_ = RemappingStage; | |
| 92 root->Accept(this); | |
| 93 } | |
| 94 | |
| 95 void TextureGenerator::AllocateImageArray() { | |
| 96 image_data_.reset(new ImagePtr[discovered_ids_.size()]); | |
| 97 images_generated_ = 0; | |
| 98 } | |
| 99 | |
| 100 void TextureGenerator::BuildTextureImages(RenderNode* root) { | |
| 101 // Pass 3: use the texture metadata to generate images for the | |
| 102 // textures, and set up the textures for use by OpenGL. This | |
| 103 // doesn't *have* to be a separate pass (it could be rolled | |
| 104 // into pass 2) but I think this is more clear and performance | |
| 105 // shouldn't be bad. | |
| 106 stage_ = ImageGenerationStage; | |
| 107 root->Accept(this); | |
| 108 } | |
| 109 | |
| 110 void TextureGenerator::HandleTexture(int* texID, | |
| 111 int width, | |
|
piman
2011/08/26 02:24:16
nit:indentation (align parameters)
| |
| 112 int height, | |
| 113 GLenum format) { | |
| 114 if (*texID == -1) return; // -1 means it's not a real texture. | |
|
piman
2011/08/26 02:24:16
nit: return on a separate line
| |
| 115 switch (stage_) { | |
| 116 case DiscoveryStage: | |
| 117 discovered_ids_.insert(*texID); | |
| 118 break; | |
| 119 case RemappingStage: | |
| 120 *texID = remapped_ids_[*texID]; | |
| 121 break; | |
| 122 case ImageGenerationStage: | |
| 123 // Only handle this one if we haven't already built a | |
| 124 // texture for its ID. | |
| 125 if (ids_for_completed_textures_.count(*texID)) | |
| 126 return; | |
| 127 GenerateImageForTexture(*texID, width, height, format); | |
| 128 ids_for_completed_textures_.insert(*texID); | |
| 129 break; | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 void TextureGenerator::GenerateImageForTexture(int texID, | |
| 134 int width, | |
|
piman
2011/08/26 02:24:16
nit: indentation
| |
| 135 int height, | |
| 136 GLenum format) { | |
| 137 int bytes_per_pixel = FormatBytesPerPixel(format); | |
| 138 DCHECK_LE(bytes_per_pixel, 4); | |
| 139 int imgID = images_generated_++; | |
| 140 image_data_[imgID].reset(new uint8[width*height*bytes_per_pixel]); | |
| 141 // Pick random colors to use for this texture. | |
| 142 uint8 random_color[4]; | |
| 143 for (int c = 0; c < 4; ++c) { | |
| 144 random_color[c] = std::rand() % 255; | |
| 145 } | |
| 146 // Create the image from those colors. | |
| 147 for (int x = 0; x < width; ++x) { | |
| 148 for (int y = 0; y < height; ++y) { | |
| 149 int pix_addr = (y * width + x) * bytes_per_pixel; | |
| 150 for (int c = 0; c < bytes_per_pixel; ++c) { | |
| 151 bool on = ((x/8) + (y/8)) % 2; | |
| 152 uint8 v = on ? random_color[c] : ~random_color[c]; | |
| 153 (image_data_[imgID])[pix_addr + c] = v; | |
| 154 } | |
| 155 if (bytes_per_pixel == 4) { // Randomize alpha. | |
| 156 image_data_[imgID][pix_addr + 3] = std::rand() % 255; | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 // Set up GL texture. | |
| 161 glBindTexture(GL_TEXTURE_2D, texID); | |
| 162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 164 glPixelStorei(GL_PACK_ALIGNMENT, 1); | |
| 165 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
| 166 glTexImage2D(GL_TEXTURE_2D, | |
| 167 0, | |
|
piman
2011/08/26 02:24:16
nit: align arguments
| |
| 168 format, | |
| 169 width, height, | |
| 170 0, | |
| 171 format, | |
| 172 GL_UNSIGNED_BYTE, | |
| 173 image_data_[imgID].get()); | |
| 174 } | |
| 175 | |
| OLD | NEW |