Beispiel #1
0
IceTBoolean icetGLIsInitialized(void)
{
    if (icetStateGetType(ICET_GL_INITIALIZED) != ICET_NULL) {
        IceTBoolean initialized;
        icetGetBooleanv(ICET_GL_INITIALIZED, &initialized);
        if (initialized) {
            return ICET_TRUE;
        }
    }
    return ICET_FALSE;
}
Beispiel #2
0
IceTBoolean icetIsEnabled(IceTEnum pname)
{
    IceTBoolean isEnabled;

    if ((pname < ICET_STATE_ENABLE_START) || (pname >= ICET_STATE_ENABLE_END)) {
        icetRaiseError("Bad value to icetIsEnabled", ICET_INVALID_VALUE);
        return ICET_FALSE;
    }
    icetGetBooleanv(pname, &isEnabled);
    return isEnabled;
}
// ****************************************************************************
//  Function: SendImageToRenderNodes
//
//  Purpose: IceT distinguishes between `tile nodes' and `render nodes'.  All
//           nodes assist in image composition, but final images are only
//           collected on tile nodes.
//           Unfortunately various post-rendering algorithms in VisIt do not
//           make this distinction, which in IceT parlance means we assume all
//           nodes are tile nodes.  This method should send out the image to
//           all other nodes, so we can still utilize IceT by blurring that
//           distinction so that the rest of VisIt never knows.
//
//  Programmer: Tom Fogal
//  Creation:   August 7, 2008
//
// ****************************************************************************
static void
SendImageToRenderNodes(int width, int height, bool Z,
                       GLubyte * const pixels,
                       GLuint * const depth)
{
    GLint n_tiles, n_procs, rank;
    GLboolean have_image;

    ICET(icetGetIntegerv(ICET_NUM_TILES, &n_tiles));
    ICET(icetGetIntegerv(ICET_NUM_PROCESSES, &n_procs));
    ICET(icetGetIntegerv(ICET_RANK, &rank));
    ICET(icetGetBooleanv(ICET_COLOR_BUFFER_VALID, &have_image));

    //              4: assuming GL_RGBA.
    MPI_Bcast(pixels, 4*width*height, MPI_BYTE, 0, VISIT_MPI_COMM);
    if(Z) {
        MPI_Bcast(depth, width*height, MPI_UNSIGNED, 0, VISIT_MPI_COMM);
    }
}
Beispiel #4
0
IceTImage icetDrawFrame(const IceTDouble *projection_matrix,
                        const IceTDouble *modelview_matrix,
                        const IceTFloat *background_color)
{
    IceTInt frame_count;
    IceTImage image;
    IceTDouble render_time;
    IceTDouble buf_read_time;
    IceTDouble compose_time;
    IceTDouble total_time;

    icetRaiseDebug("In icetDrawFrame");

    {
        IceTBoolean isDrawing;
        icetGetBooleanv(ICET_IS_DRAWING_FRAME, &isDrawing);
        if (isDrawing) {
            icetRaiseError("Recursive frame draw detected.",
                           ICET_INVALID_OPERATION);
            return icetImageNull();
        }
    }

    icetStateResetTiming();
    icetTimingDrawFrameBegin();

    icetStateSetDoublev(ICET_PROJECTION_MATRIX, 16, projection_matrix);
    icetStateSetDoublev(ICET_MODELVIEW_MATRIX, 16, modelview_matrix);

    drawUseBackgroundColor(background_color);

    icetGetIntegerv(ICET_FRAME_COUNT, &frame_count);
    frame_count++;
    icetStateSetIntegerv(ICET_FRAME_COUNT, 1, &frame_count);

    drawProjectBounds();

    {
        IceTEnum strategy;
        icetGetEnumv(ICET_STRATEGY, &strategy);

        /* drawCollectTileInformation does an allgather to get information
         * about the tiles in other processes.  These variables are
         * ICET_ALL_CONTAINED_TILES_MASKS, ICET_TILE_CONTRIB_COUNTS, and
         * ICET_TOTAL_IMAGE_COUNT.  However, the sequential strategy ignores
         * this information and just uses all processes for all tiles.  When
         * compositing a single tile, this is a fine strategy and we can save
         * a significant proportion of frame time by skipping this step. */
        if (strategy != ICET_STRATEGY_SEQUENTIAL) {
            drawCollectTileInformation();
        }
    }

    {
        IceTInt tile_displayed;
        icetGetIntegerv(ICET_TILE_DISPLAYED, &tile_displayed);

        if (tile_displayed >= 0) {
            const IceTInt *tile_viewports
                = icetUnsafeStateGetInteger(ICET_TILE_VIEWPORTS);
            IceTInt num_pixels = (  tile_viewports[4*tile_displayed+2]
                                  * tile_viewports[4*tile_displayed+3] );
            icetStateSetInteger(ICET_VALID_PIXELS_TILE, tile_displayed);
            icetStateSetInteger(ICET_VALID_PIXELS_OFFSET, 0);
            icetStateSetInteger(ICET_VALID_PIXELS_NUM, num_pixels);
        } else {
            icetStateSetInteger(ICET_VALID_PIXELS_TILE, -1);
            icetStateSetInteger(ICET_VALID_PIXELS_OFFSET, 0);
            icetStateSetInteger(ICET_VALID_PIXELS_NUM, 0);
        }
    }

    image = drawInvokeStrategy();

    /* Calculate times. */
    icetGetDoublev(ICET_RENDER_TIME, &render_time);
    icetGetDoublev(ICET_BUFFER_READ_TIME, &buf_read_time);

    icetTimingDrawFrameEnd();

    icetGetDoublev(ICET_TOTAL_DRAW_TIME, &total_time);

    compose_time = total_time - render_time - buf_read_time;
    icetStateSetDouble(ICET_COMPOSITE_TIME, compose_time);

    icetStateSetDouble(ICET_BUFFER_WRITE_TIME, 0.0);

    icetStateCheckMemory();

    return image;
}
// ****************************************************************************
//  Method: Readback
//
//  Purpose: Reads back the image buffer from IceT.
//
//  Programmer: Tom Fogal
//  Creation:   June 20, 2008
//
//  Modifications:
//
//    Tom Fogal, Tue Jul  1 11:06:55 EDT 2008
//    Hack the number of scalars in the vtkImageData we create to be 4, to
//    match the kind of buffer IceT gives us.  This allows us to skip an
//    expensive GL_RGBA -> GL_RGB conversion.
//    Also, use a void*; don't know why it was a uchar* before ...
//
//    Tom Fogal, Wed Jul  2 11:05:07 EDT 2008
//    Readback and send/recv the Z buffer (unconditionally...).
//
//    Tom Fogal, Thu Jul 17 17:02:40 EDT 2008
//    Repurposed viewported argument for a boolean to grab Z.
//
//    Tom Fogal, Mon Jul 28 14:44:28 EDT 2008
//    Don't ask IceT for Z if we're not going to use it anyway.
//
//    Tom Fogal, Mon Sep  1 14:21:46 EDT 2008
//    Removed asserts / dependence on NDEBUG.
//
//    Hank Childs, Mon Dec 29 18:24:05 CST 2008
//    Make an image have 3 components, not 4, since 3 is better supported
//    throughout VisIt (including saving TIFFs).
//
//    Hank Childs, Thu Jan 15 11:07:53 CST 2009
//    Changed GetSize call to GetCaptureRegion, since that works for 2D.
//
//    Hank Childs, Fri Feb  6 15:47:17 CST 2009
//    Fix memory leak.
//
//    Burlen Loring, Tue Sep  1 14:26:30 PDT 2015
//    sync up with network manager(base class) order compositing refactor
//
// ****************************************************************************
avtImage_p
IceTNetworkManager::Readback(VisWindow * const viswin,
                             bool readZ) const
{
    GLboolean have_image;

    ICET(icetGetBooleanv(ICET_COLOR_BUFFER_VALID, &have_image));

    int width=-42, height=-42, width_start, height_start;
    // This basically gets the width and the height.
    // The distinction is for 2D rendering, where we only want the
    // width and the height of the viewport.
    viswin->GetCaptureRegion(width_start, height_start, width, height,
                             renderState.viewportedMode);

    GLubyte *pixels = NULL;
    GLuint *depth = NULL;

    if(readZ && have_image == GL_TRUE)
    {
        depth = icetGetDepthBuffer();
        DEBUG_ONLY(ICET_CHECK_ERROR);
    }
    // We can't delete pointers IceT gives us.  However if we're a receiving
    // node, we'll dynamically allocate our buffers and thus need to deallocate
    // them.
    bool dynamic = false;

    if(have_image == GL_TRUE)
    {
        // We have an image.  First read it back from IceT.
        pixels = icetGetColorBuffer();
        DEBUG_ONLY(ICET_CHECK_ERROR);

        this->VerifyColorFormat(); // Bail out if we don't get GL_RGBA data.
    } else {
        // We don't have an image -- we need to receive it from our buddy.
        // Purpose of static pixel_ptr ... if I delete this memory too soon (i.e. along
        // with "depth"), then there is a crash ... it is being used after the function
        // exits.  So just wait until the next render to free it.
        static GLubyte *pixel_ptr = NULL;
        if (pixel_ptr != NULL)
           delete [] pixel_ptr;
        pixel_ptr = new GLubyte[4*width*height];
        pixels = pixel_ptr;
        depth = new GLuint[width*height];

        dynamic = true;
    }
    SendImageToRenderNodes(width, height, readZ, pixels, depth);

    vtkImageData *image = avtImageRepresentation::NewImage(width, height);
    // NewImage assumes we want a 3-component ("GL_RGB") image, but IceT gives
    // us back data in a GL_RGBA format.  So we just reset the number of
    // components and reallocate the data; unfortunately this means we do an
    // allocate in NewImage and then immediately throw it away when doing an
    // allocate here.
    image->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
    {
        unsigned char *img_pix = (unsigned char *) image->GetScalarPointer();
        const int numPix = width*height;
        for (int i = 0 ; i < numPix ; i++)
        {
            *img_pix++ = *pixels++;
            *img_pix++ = *pixels++;
            *img_pix++ = *pixels++;
            pixels++; // Alpha
        }
    }
    float *visit_depth_buffer = NULL;

    if(readZ)
    {
        debug4 << "Converting depth values ..." << std::endl;
        visit_depth_buffer = utofv(depth, width*height);
    }

    avtSourceFromImage screenCapSrc(image, visit_depth_buffer);
    avtImage_p visit_img = screenCapSrc.GetTypedOutput();
    visit_img->Update(screenCapSrc.GetGeneralContract());
    visit_img->SetSource(NULL);
    image->Delete();
    delete[] visit_depth_buffer;
    if(dynamic)
    {
        delete[] depth;
    }

    debug3 << "Readback complete." << std::endl;

    return visit_img;
}
Beispiel #6
0
static IceTImage vtreeCompose(void)
{
    GLint rank, num_proc;
    GLint num_tiles;
    GLint max_pixels;
    GLint *display_nodes;
    GLint tile_displayed;
    GLboolean *all_contained_tmasks;
    GLint *tile_viewports;
    IceTImage imageBuffer;
    IceTSparseImage inImage, outImage;
    struct node_info *info;
    struct node_info *my_info;
    int tile, node;
    int tiles_transfered;
    int tile_held = -1;

    icetRaiseDebug("In vtreeCompose");

  /* Get state. */
    icetGetIntegerv(ICET_RANK, &rank);
    icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);
    icetGetIntegerv(ICET_NUM_TILES, &num_tiles);
    icetGetIntegerv(ICET_TILE_MAX_PIXELS, &max_pixels);
    display_nodes = icetUnsafeStateGet(ICET_DISPLAY_NODES);
    tile_viewports = icetUnsafeStateGet(ICET_TILE_VIEWPORTS);
    icetGetIntegerv(ICET_TILE_DISPLAYED, &tile_displayed);

  /* Allocate buffers. */
    icetResizeBuffer(  icetFullImageSize(max_pixels)
                     + icetSparseImageSize(max_pixels)*2
                     + sizeof(struct node_info)*num_proc
                     + sizeof(GLboolean)*num_proc*num_tiles);
    imageBuffer = icetReserveBufferMem(icetFullImageSize(max_pixels));
    inImage     = icetReserveBufferMem(icetSparseImageSize(max_pixels));
    outImage    = icetReserveBufferMem(icetSparseImageSize(max_pixels));
    info        = icetReserveBufferMem(sizeof(struct node_info)*num_proc);
    all_contained_tmasks
                = icetReserveBufferMem(sizeof(GLboolean)*num_proc*num_tiles);

    icetGetBooleanv(ICET_ALL_CONTAINED_TILES_MASKS, all_contained_tmasks);
    
  /* Initialize info array. */
    for (node = 0; node < num_proc; node++) {
        info[node].rank = node;
        info[node].tile_held = -1;        /* Id of tile image held in memory. */
        info[node].num_contained = 0;        /* # of images to be rendered. */
        for (tile = 0; tile < num_tiles; tile++) {
            if (all_contained_tmasks[node*num_tiles + tile]) {
                info[node].num_contained++;
            }
        }
    }

#define CONTAINS_TILE(nodei, tile)                                \
    (all_contained_tmasks[info[nodei].rank*num_tiles+(tile)])

    tile_held = -1;
    do {
        int recv_node;

        tiles_transfered = 0;
        sort_by_contained(info, num_proc);
        for (node = 0; node < num_proc; node++) {
            info[node].tile_sending = -1;
            info[node].tile_receiving = -1;
        }

        for (recv_node = 0; recv_node < num_proc; recv_node++) {
            struct node_info *recv_info = info + recv_node;

            if (recv_info->tile_receiving >= 0) continue;

            if (recv_info->tile_held >= 0) {
              /* This node is holding a tile.  It must either send or
                 receive this tile. */
                if (find_sender(info, num_proc, recv_node, recv_info->tile_held,
                                display_nodes[recv_info->tile_held],
                                num_tiles, all_contained_tmasks)) {
                    tiles_transfered = 1;
                    continue;
                }

              /* Could not find a match for a sender, how about someone who
                 can receive it? */
                if (   (recv_info->tile_sending < 0)
                    && (recv_info->rank != display_nodes[recv_info->tile_held])
                    && find_receiver(info, num_proc, recv_node,
                                     recv_info->tile_held,
                                     display_nodes[recv_info->tile_held],
                                     num_tiles, all_contained_tmasks) ) {
                    tiles_transfered = 1;
                } else {
                  /* Could not send or receive.  Give up. */
                    continue;
                }
            }

          /* OK.  Let's try to receive any tile that we still have. */
            for (tile = 0; tile < num_tiles; tile++) {
                if (   (   !CONTAINS_TILE(recv_node, tile)
                        && (display_nodes[tile] != recv_info->rank) )
                    || (recv_info->tile_sending == tile) ) continue;
                if (find_sender(info, num_proc, recv_node, tile,
                                display_nodes[tile], num_tiles,
                                all_contained_tmasks)) {
                    tiles_transfered = 1;
                    break;
                }
            }
        }

      /* Now that we figured out who is sending to who, do the actual
         send and receive. */
        my_info = NULL;
        for (node = 0; node < num_proc; node++) {
            if (info[node].rank == rank) {
                my_info = info + node;
                break;
            }
        }

        do_send_receive(my_info, tile_held, max_pixels, num_tiles,
                        tile_viewports, all_contained_tmasks,
                        imageBuffer, inImage, outImage);

        tile_held = my_info->tile_held;

    } while (tiles_transfered);

  /* It's possible that a composited image ended up on a processor that        */
  /* is not the display node for that image.  Do one last round of        */
  /* transfers to make sure all the tiles ended up in the right place.        */
    for (node = 0; node < num_proc; node++) {
        if (info[node].rank == rank) {
            my_info = info + node;
            break;
        }
    }
    my_info->tile_receiving = -1;
    my_info->tile_sending = -1;
    if ((my_info->tile_held >= 0) && (my_info->tile_held != tile_displayed)) {
      /* I'm holding an image that does not belong to me.  Ship it off. */
        my_info->tile_sending = my_info->tile_held;
        my_info->send_dest = display_nodes[my_info->tile_held];
        my_info->tile_held = -1;
    }
    if ((my_info->tile_held != tile_displayed) && (tile_displayed >= 0)) {
      /* Someone may be holding an image that belongs to me.  Check. */
        for (node = 0; node < num_proc; node++) {
            if (info[node].tile_held == tile_displayed) {
                my_info->tile_receiving = tile_displayed;
                my_info->recv_src = info[node].rank;
                my_info->tile_held = tile_displayed;
                break;
            }
        }
    }
    do_send_receive(my_info, tile_held,
                    max_pixels, num_tiles, tile_viewports, all_contained_tmasks,
                    imageBuffer, inImage, outImage);
    tile_held = my_info->tile_held;

  /* Hacks for when "this" tile was not rendered. */
    if ((tile_displayed >= 0) && (tile_displayed != tile_held)) {
        if (all_contained_tmasks[rank*num_tiles + tile_displayed]) {
          /* Only "this" node draws "this" tile.  Because the image never */
          /* needed to be transferred, it was never rendered above.  Just */
          /* render it now.                                                  */
            icetRaiseDebug("Rendering tile to display.");
          /* This may uncessarily read a buffer if not outputing an input
             buffer */
            icetGetTileImage(tile_displayed, imageBuffer);
        } else {
          /* "This" tile is blank. */
            icetRaiseDebug("Returning blank image.");
            icetInitializeImage(imageBuffer, max_pixels);
            icetClearImage(imageBuffer);
        }
    }

    return imageBuffer;
}