private int packBitmaps(Atlas.Type type, int width, int height, Atlas.Entry entry) { int total = 0; Atlas atlas = new Atlas(type, width, height); final int count = mBitmaps.size(); for (int i = 0; i < count; i++) { final Bitmap bitmap = mBitmaps.get(i); if (atlas.pack(bitmap.getWidth(), bitmap.getHeight(), entry) != null) { total++; } } return total; }
/** * Renders a list of bitmaps into the atlas. The position of each bitmap was decided by the * packing algorithm and will be honored by this method. * * @param buffer The buffer to render the atlas entries into * @param atlas The atlas to pack the bitmaps into * @param packCount The number of bitmaps that will be packed in the atlas * @return true if the atlas was rendered, false otherwise */ @SuppressWarnings("MismatchedReadAndWriteOfArray") private boolean renderAtlas(GraphicBuffer buffer, Atlas atlas, int packCount) { // Use a Source blend mode to improve performance, the target bitmap // will be zero'd out so there's no need to waste time applying blending final Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); // We always render the atlas into a bitmap. This bitmap is then // uploaded into the GraphicBuffer using OpenGL to swizzle the content final Bitmap atlasBitmap = Bitmap.createBitmap(buffer.getWidth(), buffer.getHeight(), Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(atlasBitmap); final Atlas.Entry entry = new Atlas.Entry(); mAtlasMap = new long[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT]; long[] atlasMap = mAtlasMap; int mapIndex = 0; boolean result = false; final long startRender = System.nanoTime(); final int count = mBitmaps.size(); for (int i = 0; i < count; i++) { final Bitmap bitmap = mBitmaps.get(i); if (atlas.pack(bitmap.getWidth(), bitmap.getHeight(), entry) != null) { // We have more bitmaps to pack than the current configuration // says, we were most likely not able to detect a change in the // list of preloaded drawables, abort and delete the configuration if (mapIndex >= mAtlasMap.length) { deleteDataFile(); break; } canvas.save(); canvas.translate(entry.x, entry.y); canvas.drawBitmap(bitmap, 0.0f, 0.0f, null); canvas.restore(); atlasMap[mapIndex++] = bitmap.refSkPixelRef(); atlasMap[mapIndex++] = entry.x; atlasMap[mapIndex++] = entry.y; } } final long endRender = System.nanoTime(); releaseCanvas(canvas, atlasBitmap); result = nUploadAtlas(buffer, atlasBitmap); atlasBitmap.recycle(); final long endUpload = System.nanoTime(); if (DEBUG_ATLAS) { float renderDuration = (endRender - startRender) / 1000.0f / 1000.0f; float uploadDuration = (endUpload - endRender) / 1000.0f / 1000.0f; Log.d( LOG_TAG, String.format( "Rendered atlas in %.2fms (%.2f+%.2fms)", renderDuration + uploadDuration, renderDuration, uploadDuration)); } return result; }