<commit_before>
#ifdef ATOMIC_PLATFORM_OSX
#include <ThirdParty/GLEW/glew.h>
#endif

#include <include/cef_render_handler.h>

#include <Atomic/IO/Log.h>

#include <Atomic/Resource/ResourceCache.h>
#include <Atomic/Graphics/Graphics.h>
#include <Atomic/Graphics/Technique.h>

#include "WebClient.h"
#include "WebTexture2D.h"

namespace Atomic
{

class WebTexture2DPrivate : public CefRenderHandler
{
    friend class WebTexture2D;

public:

    IMPLEMENT_REFCOUNTING(WebTexture2DPrivate)

    WebTexture2DPrivate(WebTexture2D* webTexture2D)
    {
        webTexture2D_ = webTexture2D;
    }

    void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE
    {
        if (!show)
        {
            // Clear the popup rectangle.
            ClearPopupRects();
        }
    }

    void OnPopupSize(CefRefPtr<CefBrowser> browser, const CefRect& rect) OVERRIDE
    {
        if (rect.width <= 0 || rect.height <= 0)
        {
            ClearPopupRects();
            return;
        }

        popupRectOriginal_ = rect;
        popupRect_ = GetPopupRectInWebView(popupRectOriginal_);
    }

    CefRect GetPopupRectInWebView(const CefRect& original_rect) {

        CefRect rc(original_rect);

        // if x or y are negative, move them to 0.
        if (rc.x < 0)
            rc.x = 0;
        if (rc.y < 0)
            rc.y = 0;

        // if popup goes outside the view, try to reposition origin
        if (rc.x + rc.width > webTexture2D_->GetWidth())
            rc.x = webTexture2D_->GetWidth() - rc.width;
        if (rc.y + rc.height > webTexture2D_->GetHeight())
            rc.y = webTexture2D_->GetHeight() - rc.height;

        // if x or y became negative, move them to 0 again.
        if (rc.x < 0)
            rc.x = 0;
        if (rc.y < 0)
            rc.y = 0;

        return rc;
    }

    void ClearPopupRects()
    {
        popupRect_.Set(0, 0, 0, 0);
        popupRectOriginal_.Set(0, 0, 0, 0);
    }

    bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) OVERRIDE
    {
        rect = CefRect(0, 0, webTexture2D_->GetWidth(), webTexture2D_->GetHeight());
        return true;
    }

#ifdef ATOMIC_PLATFORM_OSX
    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects,
                 const void *buffer, int width, int height) OVERRIDE
    {
        glEnable(GL_TEXTURE_2D);

        if (type == PET_VIEW)
        {
            glBindTexture(GL_TEXTURE_2D, webTexture2D_->GetTexture2D()->GetGPUObject());

            glPixelStorei(GL_UNPACK_ROW_LENGTH, width);

            if (dirtyRects.size() == 1 &&
                    dirtyRects[0] == CefRect(0, 0, webTexture2D_->GetWidth(), webTexture2D_->GetHeight()))
            {
                Texture2D* tex = webTexture2D_->texture_;
                glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
                glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
                tex->SetData(0, 0, 0, width, height, buffer);
            }
            else
            {
                // Update just the dirty rectangles.
                CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();

                for (; i != dirtyRects.end(); ++i)
                {
                    const CefRect& rect = *i;

                    glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x);
                    glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y);
                    glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,
                                    rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                                    buffer);

                }

            }

            glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

            glBindTexture(GL_TEXTURE_2D, 0);
        }
        else if (type == PET_POPUP && popupRect_.width > 0 && popupRect_.height > 0)
        {
            int skip_pixels = 0, x = popupRect_.x;
            int skip_rows = 0, y = popupRect_.y;
            int w = width;
            int h = height;
            int viewwidth = webTexture2D_->GetWidth();
            int viewheight = webTexture2D_->GetHeight();

            // Adjust the popup to fit inside the view.
            if (x < 0)
            {
                skip_pixels = -x;
                x = 0;
            }
            if (y < 0)
            {
                skip_rows = -y;
                y = 0;
            }
            if (x + w > viewwidth)
            {
                w -= x + w - viewwidth;
            }
            if (y + h > viewheight)
            {
                h -= y + h - viewheight;
            }

            glBindTexture(GL_TEXTURE_2D, webTexture2D_->GetTexture2D()->GetGPUObject());

            // Update the popup rectangle.
            glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
            glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);

            glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA,
                            GL_UNSIGNED_INT_8_8_8_8_REV, buffer);

            glBindTexture(GL_TEXTURE_2D, 0);

            glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
        }

        glDisable(GL_TEXTURE_2D);

    }
#else

    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects,
                 const void *buffer, int width, int height) OVERRIDE
    {
        webTexture2D_->GetTexture2D()->SetData(0, 0, 0, width, height, buffer);
    }

#endif

private:

    CefRect popupRect_;
    CefRect popupRectOriginal_;

    WeakPtr<WebTexture2D> webTexture2D_;

};

WebTexture2D::WebTexture2D(Context* context) : WebRenderHandler(context)
{
    d_ = new WebTexture2DPrivate(this);
    d_->AddRef();

    texture_ = new Texture2D(context_);
    texture_->SetNumLevels(1);
    texture_->SetFilterMode(FILTER_BILINEAR);
}

WebTexture2D::~WebTexture2D()
{
    //d_->Release();
}

CefRenderHandler* WebTexture2D::GetCEFRenderHandler()
{
    return d_;
}

int WebTexture2D::GetWidth() const
{
    return texture_->GetWidth();
}

int WebTexture2D::GetHeight() const
{
    return texture_->GetHeight();
}

void WebTexture2D::SetSize(int width, int height)
{
    if (width == texture_->GetWidth() && height == texture_->GetHeight())
        return;

    texture_->SetSize(width, height, Graphics::GetRGBAFormat(), TEXTURE_DYNAMIC);

}

}
<commit_msg>Use nearest filtering for UI view, only update full buffer on PET_VIEW<commit_after>
#ifdef ATOMIC_PLATFORM_OSX
#include <ThirdParty/GLEW/glew.h>
#endif

#include <include/cef_render_handler.h>

#include <Atomic/IO/Log.h>

#include <Atomic/Resource/ResourceCache.h>
#include <Atomic/Graphics/Graphics.h>
#include <Atomic/Graphics/Technique.h>

#include "WebClient.h"
#include "WebTexture2D.h"

namespace Atomic
{

class WebTexture2DPrivate : public CefRenderHandler
{
    friend class WebTexture2D;

public:

    IMPLEMENT_REFCOUNTING(WebTexture2DPrivate)

    WebTexture2DPrivate(WebTexture2D* webTexture2D)
    {
        webTexture2D_ = webTexture2D;
    }

    void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE
    {
        if (!show)
        {
            // Clear the popup rectangle.
            ClearPopupRects();
        }
    }

    void OnPopupSize(CefRefPtr<CefBrowser> browser, const CefRect& rect) OVERRIDE
    {
        if (rect.width <= 0 || rect.height <= 0)
        {
            ClearPopupRects();
            return;
        }

        popupRectOriginal_ = rect;
        popupRect_ = GetPopupRectInWebView(popupRectOriginal_);
    }

    CefRect GetPopupRectInWebView(const CefRect& original_rect) {

        CefRect rc(original_rect);

        // if x or y are negative, move them to 0.
        if (rc.x < 0)
            rc.x = 0;
        if (rc.y < 0)
            rc.y = 0;

        // if popup goes outside the view, try to reposition origin
        if (rc.x + rc.width > webTexture2D_->GetWidth())
            rc.x = webTexture2D_->GetWidth() - rc.width;
        if (rc.y + rc.height > webTexture2D_->GetHeight())
            rc.y = webTexture2D_->GetHeight() - rc.height;

        // if x or y became negative, move them to 0 again.
        if (rc.x < 0)
            rc.x = 0;
        if (rc.y < 0)
            rc.y = 0;

        return rc;
    }

    void ClearPopupRects()
    {
        popupRect_.Set(0, 0, 0, 0);
        popupRectOriginal_.Set(0, 0, 0, 0);
    }

    bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) OVERRIDE
    {
        rect = CefRect(0, 0, webTexture2D_->GetWidth(), webTexture2D_->GetHeight());
        return true;
    }

#ifdef ATOMIC_PLATFORM_OSX
    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects,
                 const void *buffer, int width, int height) OVERRIDE
    {
        glEnable(GL_TEXTURE_2D);

        if (type == PET_VIEW)
        {
            glBindTexture(GL_TEXTURE_2D, webTexture2D_->GetTexture2D()->GetGPUObject());

            glPixelStorei(GL_UNPACK_ROW_LENGTH, width);

            if (dirtyRects.size() == 1 &&
                    dirtyRects[0] == CefRect(0, 0, webTexture2D_->GetWidth(), webTexture2D_->GetHeight()))
            {
                Texture2D* tex = webTexture2D_->texture_;
                glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
                glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
                tex->SetData(0, 0, 0, width, height, buffer);
            }
            else
            {
                // Update just the dirty rectangles.
                CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();

                for (; i != dirtyRects.end(); ++i)
                {
                    const CefRect& rect = *i;

                    glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x);
                    glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y);
                    glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,
                                    rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                                    buffer);

                }

            }

            glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

            glBindTexture(GL_TEXTURE_2D, 0);
        }
        else if (type == PET_POPUP && popupRect_.width > 0 && popupRect_.height > 0)
        {
            int skip_pixels = 0, x = popupRect_.x;
            int skip_rows = 0, y = popupRect_.y;
            int w = width;
            int h = height;
            int viewwidth = webTexture2D_->GetWidth();
            int viewheight = webTexture2D_->GetHeight();

            // Adjust the popup to fit inside the view.
            if (x < 0)
            {
                skip_pixels = -x;
                x = 0;
            }
            if (y < 0)
            {
                skip_rows = -y;
                y = 0;
            }
            if (x + w > viewwidth)
            {
                w -= x + w - viewwidth;
            }
            if (y + h > viewheight)
            {
                h -= y + h - viewheight;
            }

            glBindTexture(GL_TEXTURE_2D, webTexture2D_->GetTexture2D()->GetGPUObject());

            // Update the popup rectangle.
            glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
            glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);

            glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA,
                            GL_UNSIGNED_INT_8_8_8_8_REV, buffer);

            glBindTexture(GL_TEXTURE_2D, 0);

            glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
            glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
        }

        glDisable(GL_TEXTURE_2D);

    }
#else

    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects,
                 const void *buffer, int width, int height) OVERRIDE
    {
        if (type == PET_VIEW)
        {
            webTexture2D_->GetTexture2D()->SetData(0, 0, 0, width, height, buffer);
        }
    }

#endif

private:

    CefRect popupRect_;
    CefRect popupRectOriginal_;

    WeakPtr<WebTexture2D> webTexture2D_;

};

WebTexture2D::WebTexture2D(Context* context) : WebRenderHandler(context)
{
    d_ = new WebTexture2DPrivate(this);
    d_->AddRef();

    texture_ = new Texture2D(context_);
    texture_->SetNumLevels(1);
    texture_->SetFilterMode(FILTER_NEAREST);
}

WebTexture2D::~WebTexture2D()
{
    //d_->Release();
}

CefRenderHandler* WebTexture2D::GetCEFRenderHandler()
{
    return d_;
}

int WebTexture2D::GetWidth() const
{
    return texture_->GetWidth();
}

int WebTexture2D::GetHeight() const
{
    return texture_->GetHeight();
}

void WebTexture2D::SetSize(int width, int height)
{
    if (width == texture_->GetWidth() && height == texture_->GetHeight())
        return;

    texture_->SetSize(width, height, Graphics::GetRGBAFormat(), TEXTURE_DYNAMIC);

}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsTransferable.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 06:17:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_TRANSFERABLE_HXX
#define SD_SLIDESORTER_TRANSFERABLE_HXX

#include "sdxfer.hxx"

class SdDrawDocument;
namespace sd
{
    class pWorkView;
    namespace slidesorter
    {
        class SlideSorterViewShell;
    }
}

namespace sd { namespace slidesorter { namespace controller {

/** This class exists to have DragFinished call the correct object: the
    SlideSorterViewShell instead of the old SlideView.
*/
class Transferable
    : public SdTransferable
{
public:
    Transferable (
        SdDrawDocument* pSrcDoc,
        ::sd::View* pWorkView,
        BOOL bInitOnGetData,
        SlideSorterViewShell* pViewShell);

    virtual ~Transferable (void);

    virtual void DragFinished (sal_Int8 nDropAction);

private:
    SlideSorterViewShell* mpViewShell;
};

} } } // end of namespace ::sd::slidesorter::controller

#endif
<commit_msg>INTEGRATION: CWS impress82 (1.3.104); FILE MERGED 2006/01/16 16:19:19 af 1.3.104.1: #126734# Listening for ViewShell being destroyed.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsTransferable.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-01-24 14:43:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_TRANSFERABLE_HXX
#define SD_SLIDESORTER_TRANSFERABLE_HXX

#include "sdxfer.hxx"

class SdDrawDocument;
namespace sd
{
    class pWorkView;
    namespace slidesorter
    {
        class SlideSorterViewShell;
    }
}

namespace sd { namespace slidesorter { namespace controller {

/** This class exists to have DragFinished call the correct object: the
    SlideSorterViewShell instead of the old SlideView.
*/
class Transferable
    : public SdTransferable
{
public:
    Transferable (
        SdDrawDocument* pSrcDoc,
        ::sd::View* pWorkView,
        BOOL bInitOnGetData,
        SlideSorterViewShell* pViewShell);

    virtual ~Transferable (void);

    virtual void DragFinished (sal_Int8 nDropAction);

private:
    SlideSorterViewShell* mpViewShell;

    virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
};

} } } // end of namespace ::sd::slidesorter::controller

#endif
<|endoftext|>


<commit_before>/* Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow_serving/model_servers/http_rest_api_handler.h"

#include <string>

#include "google/protobuf/any.pb.h"
#include "google/protobuf/util/json_util.h"
#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/cc/saved_model/signature_constants.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/threadpool_options.h"
#include "tensorflow_serving/apis/model.pb.h"
#include "tensorflow_serving/apis/predict.pb.h"
#include "tensorflow_serving/core/servable_handle.h"
#include "tensorflow_serving/model_servers/get_model_status_impl.h"
#include "tensorflow_serving/model_servers/server_core.h"
#include "tensorflow_serving/servables/tensorflow/classification_service.h"
#include "tensorflow_serving/servables/tensorflow/get_model_metadata_impl.h"
#include "tensorflow_serving/servables/tensorflow/predict_impl.h"
#include "tensorflow_serving/servables/tensorflow/regression_service.h"
#include "tensorflow_serving/util/json_tensor.h"

namespace tensorflow {
namespace serving {

using protobuf::util::JsonPrintOptions;
using protobuf::util::MessageToJsonString;
using tensorflow::serving::ServerCore;
using tensorflow::serving::TensorflowPredictor;

const char* const HttpRestApiHandler::kPathRegex = "(?i)/v1/.*";

HttpRestApiHandler::HttpRestApiHandler(const RunOptions& run_options,
                                       ServerCore* core)
    : run_options_(run_options),
      core_(core),
      predictor_(new TensorflowPredictor()),
      prediction_api_regex_(
          R"((?i)/v1/models/([^/:]+)(?:(?:/versions/(\d+))|(?:/labels/(\w+)))?:(classify|regress|predict))"),
      modelstatus_api_regex_(
          R"((?i)/v1/models(?:/([^/:]+))?(?:(?:/versions/(\d+))|(?:/labels/(\w+)))?(?:\/(metadata))?)") {
}

HttpRestApiHandler::~HttpRestApiHandler() {}

namespace {

void AddHeaders(std::vector<std::pair<string, string>>* headers) {
  headers->push_back({"Content-Type", "application/json"});
}

Status FillModelSpecWithNameVersionAndLabel(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view> model_version_label,
    ::tensorflow::serving::ModelSpec* model_spec) {
  model_spec->set_name(string(model_name));

  if (model_version.has_value() && model_version_label.has_value()) {
    return errors::InvalidArgument(
        "Both model version (", model_version.value(),
        ") and model version label (", model_version_label.value(),
        ") cannot be supplied.");
  }

  if (model_version.has_value()) {
    model_spec->mutable_version()->set_value(model_version.value());
  }
  if (model_version_label.has_value()) {
    model_spec->set_version_label(string(model_version_label.value()));
  }
  return Status::OK();
}

}  // namespace

Status HttpRestApiHandler::ProcessRequest(
    const absl::string_view http_method, const absl::string_view request_path,
    const absl::string_view request_body,
    std::vector<std::pair<string, string>>* headers, string* output) {
  headers->clear();
  output->clear();
  AddHeaders(headers);
  string model_name;
  string model_version_str;
  string model_version_label_str;
  string method;
  string model_subresource;
  Status status = errors::InvalidArgument("Malformed request: ", http_method,
                                          " ", request_path);

  // Parse request parameters
  bool parse_successful = false;
  if (http_method == "POST") {
    parse_successful =
        RE2::FullMatch(string(request_path), prediction_api_regex_, &model_name,
                       &model_version_str, &model_version_label_str, &method);
  } else if (http_method == "GET") {
    parse_successful = RE2::FullMatch(
        string(request_path), modelstatus_api_regex_, &model_name,
        &model_version_str, &model_version_label_str, &model_subresource);
  }

  absl::optional<int64> model_version;
  absl::optional<absl::string_view> model_version_label;
  if (!model_version_str.empty()) {
    int64 version;
    if (!absl::SimpleAtoi(model_version_str, &version)) {
      return errors::InvalidArgument(
          "Failed to convert version: ", model_version_str, " to numeric.");
    }
    model_version = version;
  }
  if (!model_version_label_str.empty()) {
    model_version_label = model_version_label_str;
  }

  // Dispatch request to appropriate processor
  if (http_method == "POST" && parse_successful) {
    if (method == "classify") {
      status = ProcessClassifyRequest(
          model_name, model_version, model_version_label, request_body, output);
    } else if (method == "regress") {
      status = ProcessRegressRequest(model_name, model_version,
                                     model_version_label, request_body, output);
    } else if (method == "predict") {
      status = ProcessPredictRequest(model_name, model_version,
                                     model_version_label, request_body, output);
    }
  } else if (http_method == "GET" && parse_successful) {
    if (!model_subresource.empty() && model_subresource == "metadata") {
      status = ProcessModelMetadataRequest(model_name, model_version,
                                           model_version_label, output);
    } else {
      status = ProcessModelStatusRequest(model_name, model_version,
                                         model_version_label, output);
    }
  }

  MakeJsonFromStatus(status, output);
  return status;
}

Status HttpRestApiHandler::ProcessClassifyRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  ClassificationRequest request;
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request.mutable_model_spec()));
  TF_RETURN_IF_ERROR(FillClassificationRequestFromJson(request_body, &request));

  ClassificationResponse response;
  TF_RETURN_IF_ERROR(TensorflowClassificationServiceImpl::Classify(
      run_options_, core_, thread::ThreadPoolOptions(), request, &response));
  TF_RETURN_IF_ERROR(
      MakeJsonFromClassificationResult(response.result(), output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessRegressRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  RegressionRequest request;
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request.mutable_model_spec()));
  TF_RETURN_IF_ERROR(FillRegressionRequestFromJson(request_body, &request));

  RegressionResponse response;
  TF_RETURN_IF_ERROR(TensorflowRegressionServiceImpl::Regress(
      run_options_, core_, thread::ThreadPoolOptions(), request, &response));
  TF_RETURN_IF_ERROR(MakeJsonFromRegressionResult(response.result(), output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessPredictRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  PredictRequest request;
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request.mutable_model_spec()));

  JsonPredictRequestFormat format;
  TF_RETURN_IF_ERROR(FillPredictRequestFromJson(
      request_body,
      [this, &request](const string& sig,
                       ::google::protobuf::Map<string, TensorInfo>* map) {
        return this->GetInfoMap(request.model_spec(), sig, map);
      },
      &request, &format));

  PredictResponse response;
  TF_RETURN_IF_ERROR(
      predictor_->Predict(run_options_, core_, request, &response));
  TF_RETURN_IF_ERROR(MakeJsonFromTensors(response.outputs(), format, output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessModelStatusRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    string* output) {
  // We do not yet support returning status of all models
  // to be in-sync with the gRPC GetModelStatus API.
  if (model_name.empty()) {
    return errors::InvalidArgument("Missing model name in request.");
  }

  GetModelStatusRequest request;
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request.mutable_model_spec()));

  GetModelStatusResponse response;
  TF_RETURN_IF_ERROR(
      GetModelStatusImpl::GetModelStatus(core_, request, &response));
  JsonPrintOptions opts;
  opts.add_whitespace = true;
  opts.always_print_primitive_fields = true;
  // Note this is protobuf::util::Status (not TF Status) object.
  const auto& status = MessageToJsonString(response, output, opts);
  if (!status.ok()) {
    return errors::Internal("Failed to convert proto to json. Error: ",
                            status.ToString());
  }
  return Status::OK();
}

Status HttpRestApiHandler::ProcessModelMetadataRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    string* output) {
  if (model_name.empty()) {
    return errors::InvalidArgument("Missing model name in request.");
  }
  GetModelMetadataRequest request;
  // We currently only support the kSignatureDef metadata field
  request.add_metadata_field(GetModelMetadataImpl::kSignatureDef);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request.mutable_model_spec()));

  GetModelMetadataResponse response;
  TF_RETURN_IF_ERROR(
      GetModelMetadataImpl::GetModelMetadata(core_, request, &response));
  JsonPrintOptions opts;
  opts.add_whitespace = true;
  opts.always_print_primitive_fields = true;
  // TODO(b/118381513): preserving proto field names on 'Any' fields has been
  // fixed in the master branch of OSS protobuf but the TF ecosystem is
  // currently using v3.6.0 where the fix is not present. To resolve the issue
  // we invoke MessageToJsonString on invididual fields and concatenate the
  // resulting strings and make it valid JSON that conforms with the response we
  // expect.
  opts.preserve_proto_field_names = true;

  string model_spec_output;
  const auto& status1 =
      MessageToJsonString(response.model_spec(), &model_spec_output, opts);
  if (!status1.ok()) {
    return errors::Internal(
        "Failed to convert model spec proto to json. Error: ",
        status1.ToString());
  }

  tensorflow::serving::SignatureDefMap signature_def_map;
  if (response.metadata().end() ==
      response.metadata().find(GetModelMetadataImpl::kSignatureDef)) {
    return errors::Internal(
        "Failed to find 'signature_def' key in the GetModelMetadataResponse "
        "metadata map.");
  }
  bool unpack_status = response.metadata()
                           .at(GetModelMetadataImpl::kSignatureDef)
                           .UnpackTo(&signature_def_map);
  if (!unpack_status) {
    return errors::Internal(
        "Failed to unpack 'Any' object to 'SignatureDefMap'.");
  }

  string signature_def_output;
  const auto& status2 =
      MessageToJsonString(signature_def_map, &signature_def_output, opts);
  if (!status2.ok()) {
    return errors::Internal(
        "Failed to convert signature def proto to json. Error: ",
        status2.ToString());
  }

  // Concatenate the resulting strings into a valid JSON format.
  absl::StrAppend(output, "{\n");
  absl::StrAppend(output, "\"model_spec\":", model_spec_output, ",\n");
  absl::StrAppend(output, "\"metadata\": {");
  absl::StrAppend(output, "\"signature_def\": ", signature_def_output, "}\n");
  absl::StrAppend(output, "}\n");
  return Status::OK();
}

Status HttpRestApiHandler::GetInfoMap(
    const ModelSpec& model_spec, const string& signature_name,
    ::google::protobuf::Map<string, tensorflow::TensorInfo>* infomap) {
  ServableHandle<SavedModelBundle> bundle;
  TF_RETURN_IF_ERROR(core_->GetServableHandle(model_spec, &bundle));
  const string& signame =
      signature_name.empty() ? kDefaultServingSignatureDefKey : signature_name;
  auto iter = bundle->meta_graph_def.signature_def().find(signame);
  if (iter == bundle->meta_graph_def.signature_def().end()) {
    return errors::InvalidArgument("Serving signature name: \"", signame,
                                   "\" not found in signature def");
  }
  *infomap = iter->second.inputs();
  return Status::OK();
}

}  // namespace serving
}  // namespace tensorflow
<commit_msg>Introducing Arena usage to TensorFlow Serving's HTTP handlers.<commit_after>/* Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow_serving/model_servers/http_rest_api_handler.h"

#include <string>

#include "google/protobuf/any.pb.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/util/json_util.h"
#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/cc/saved_model/signature_constants.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/threadpool_options.h"
#include "tensorflow_serving/apis/model.pb.h"
#include "tensorflow_serving/apis/predict.pb.h"
#include "tensorflow_serving/core/servable_handle.h"
#include "tensorflow_serving/model_servers/get_model_status_impl.h"
#include "tensorflow_serving/model_servers/server_core.h"
#include "tensorflow_serving/servables/tensorflow/classification_service.h"
#include "tensorflow_serving/servables/tensorflow/get_model_metadata_impl.h"
#include "tensorflow_serving/servables/tensorflow/predict_impl.h"
#include "tensorflow_serving/servables/tensorflow/regression_service.h"
#include "tensorflow_serving/util/json_tensor.h"

namespace tensorflow {
namespace serving {

using protobuf::util::JsonPrintOptions;
using protobuf::util::MessageToJsonString;
using tensorflow::serving::ServerCore;
using tensorflow::serving::TensorflowPredictor;

const char* const HttpRestApiHandler::kPathRegex = "(?i)/v1/.*";

HttpRestApiHandler::HttpRestApiHandler(const RunOptions& run_options,
                                       ServerCore* core)
    : run_options_(run_options),
      core_(core),
      predictor_(new TensorflowPredictor()),
      prediction_api_regex_(
          R"((?i)/v1/models/([^/:]+)(?:(?:/versions/(\d+))|(?:/labels/(\w+)))?:(classify|regress|predict))"),
      modelstatus_api_regex_(
          R"((?i)/v1/models(?:/([^/:]+))?(?:(?:/versions/(\d+))|(?:/labels/(\w+)))?(?:\/(metadata))?)") {
}

HttpRestApiHandler::~HttpRestApiHandler() {}

namespace {

void AddHeaders(std::vector<std::pair<string, string>>* headers) {
  headers->push_back({"Content-Type", "application/json"});
}

Status FillModelSpecWithNameVersionAndLabel(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view> model_version_label,
    ::tensorflow::serving::ModelSpec* model_spec) {
  model_spec->set_name(string(model_name));

  if (model_version.has_value() && model_version_label.has_value()) {
    return errors::InvalidArgument(
        "Both model version (", model_version.value(),
        ") and model version label (", model_version_label.value(),
        ") cannot be supplied.");
  }

  if (model_version.has_value()) {
    model_spec->mutable_version()->set_value(model_version.value());
  }
  if (model_version_label.has_value()) {
    model_spec->set_version_label(string(model_version_label.value()));
  }
  return Status::OK();
}

}  // namespace

Status HttpRestApiHandler::ProcessRequest(
    const absl::string_view http_method, const absl::string_view request_path,
    const absl::string_view request_body,
    std::vector<std::pair<string, string>>* headers, string* output) {
  headers->clear();
  output->clear();
  AddHeaders(headers);
  string model_name;
  string model_version_str;
  string model_version_label_str;
  string method;
  string model_subresource;
  Status status = errors::InvalidArgument("Malformed request: ", http_method,
                                          " ", request_path);

  // Parse request parameters
  bool parse_successful = false;
  if (http_method == "POST") {
    parse_successful =
        RE2::FullMatch(string(request_path), prediction_api_regex_, &model_name,
                       &model_version_str, &model_version_label_str, &method);
  } else if (http_method == "GET") {
    parse_successful = RE2::FullMatch(
        string(request_path), modelstatus_api_regex_, &model_name,
        &model_version_str, &model_version_label_str, &model_subresource);
  }

  absl::optional<int64> model_version;
  absl::optional<absl::string_view> model_version_label;
  if (!model_version_str.empty()) {
    int64 version;
    if (!absl::SimpleAtoi(model_version_str, &version)) {
      return errors::InvalidArgument(
          "Failed to convert version: ", model_version_str, " to numeric.");
    }
    model_version = version;
  }
  if (!model_version_label_str.empty()) {
    model_version_label = model_version_label_str;
  }

  // Dispatch request to appropriate processor
  if (http_method == "POST" && parse_successful) {
    if (method == "classify") {
      status = ProcessClassifyRequest(
          model_name, model_version, model_version_label, request_body, output);
    } else if (method == "regress") {
      status = ProcessRegressRequest(model_name, model_version,
                                     model_version_label, request_body, output);
    } else if (method == "predict") {
      status = ProcessPredictRequest(model_name, model_version,
                                     model_version_label, request_body, output);
    }
  } else if (http_method == "GET" && parse_successful) {
    if (!model_subresource.empty() && model_subresource == "metadata") {
      status = ProcessModelMetadataRequest(model_name, model_version,
                                           model_version_label, output);
    } else {
      status = ProcessModelStatusRequest(model_name, model_version,
                                         model_version_label, output);
    }
  }

  MakeJsonFromStatus(status, output);
  return status;
}

Status HttpRestApiHandler::ProcessClassifyRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  ::google::protobuf::Arena arena;

  auto* request = ::google::protobuf::Arena::CreateMessage<ClassificationRequest>(&arena);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request->mutable_model_spec()));
  TF_RETURN_IF_ERROR(FillClassificationRequestFromJson(request_body, request));

  auto* response =
      ::google::protobuf::Arena::CreateMessage<ClassificationResponse>(&arena);
  TF_RETURN_IF_ERROR(TensorflowClassificationServiceImpl::Classify(
      run_options_, core_, thread::ThreadPoolOptions(), *request, response));
  TF_RETURN_IF_ERROR(
      MakeJsonFromClassificationResult(response->result(), output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessRegressRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  ::google::protobuf::Arena arena;

  auto* request = ::google::protobuf::Arena::CreateMessage<RegressionRequest>(&arena);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request->mutable_model_spec()));
  TF_RETURN_IF_ERROR(FillRegressionRequestFromJson(request_body, request));

  auto* response = ::google::protobuf::Arena::CreateMessage<RegressionResponse>(&arena);
  TF_RETURN_IF_ERROR(TensorflowRegressionServiceImpl::Regress(
      run_options_, core_, thread::ThreadPoolOptions(), *request, response));
  TF_RETURN_IF_ERROR(MakeJsonFromRegressionResult(response->result(), output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessPredictRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    const absl::string_view request_body, string* output) {
  ::google::protobuf::Arena arena;

  auto* request = ::google::protobuf::Arena::CreateMessage<PredictRequest>(&arena);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request->mutable_model_spec()));

  JsonPredictRequestFormat format;
  TF_RETURN_IF_ERROR(FillPredictRequestFromJson(
      request_body,
      [this, request](const string& sig,
                      ::google::protobuf::Map<string, TensorInfo>* map) {
        return this->GetInfoMap(request->model_spec(), sig, map);
      },
      request, &format));

  auto* response = ::google::protobuf::Arena::CreateMessage<PredictResponse>(&arena);
  TF_RETURN_IF_ERROR(
      predictor_->Predict(run_options_, core_, *request, response));
  TF_RETURN_IF_ERROR(MakeJsonFromTensors(response->outputs(), format, output));
  return Status::OK();
}

Status HttpRestApiHandler::ProcessModelStatusRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    string* output) {
  // We do not yet support returning status of all models
  // to be in-sync with the gRPC GetModelStatus API.
  if (model_name.empty()) {
    return errors::InvalidArgument("Missing model name in request.");
  }

  ::google::protobuf::Arena arena;

  auto* request = ::google::protobuf::Arena::CreateMessage<GetModelStatusRequest>(&arena);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request->mutable_model_spec()));

  auto* response =
      ::google::protobuf::Arena::CreateMessage<GetModelStatusResponse>(&arena);
  TF_RETURN_IF_ERROR(
      GetModelStatusImpl::GetModelStatus(core_, *request, response));
  JsonPrintOptions opts;
  opts.add_whitespace = true;
  opts.always_print_primitive_fields = true;
  // Note this is protobuf::util::Status (not TF Status) object.
  const auto& status = MessageToJsonString(*response, output, opts);
  if (!status.ok()) {
    return errors::Internal("Failed to convert proto to json. Error: ",
                            status.ToString());
  }
  return Status::OK();
}

Status HttpRestApiHandler::ProcessModelMetadataRequest(
    const absl::string_view model_name,
    const absl::optional<int64>& model_version,
    const absl::optional<absl::string_view>& model_version_label,
    string* output) {
  if (model_name.empty()) {
    return errors::InvalidArgument("Missing model name in request.");
  }

  ::google::protobuf::Arena arena;

  auto* request =
      ::google::protobuf::Arena::CreateMessage<GetModelMetadataRequest>(&arena);
  // We currently only support the kSignatureDef metadata field
  request->add_metadata_field(GetModelMetadataImpl::kSignatureDef);
  TF_RETURN_IF_ERROR(FillModelSpecWithNameVersionAndLabel(
      model_name, model_version, model_version_label,
      request->mutable_model_spec()));

  auto* response =
      ::google::protobuf::Arena::CreateMessage<GetModelMetadataResponse>(&arena);
  TF_RETURN_IF_ERROR(
      GetModelMetadataImpl::GetModelMetadata(core_, *request, response));
  JsonPrintOptions opts;
  opts.add_whitespace = true;
  opts.always_print_primitive_fields = true;
  // TODO(b/118381513): preserving proto field names on 'Any' fields has been
  // fixed in the master branch of OSS protobuf but the TF ecosystem is
  // currently using v3.6.0 where the fix is not present. To resolve the issue
  // we invoke MessageToJsonString on invididual fields and concatenate the
  // resulting strings and make it valid JSON that conforms with the response we
  // expect.
  opts.preserve_proto_field_names = true;

  string model_spec_output;
  const auto& status1 =
      MessageToJsonString(response->model_spec(), &model_spec_output, opts);
  if (!status1.ok()) {
    return errors::Internal(
        "Failed to convert model spec proto to json. Error: ",
        status1.ToString());
  }

  tensorflow::serving::SignatureDefMap signature_def_map;
  if (response->metadata().end() ==
      response->metadata().find(GetModelMetadataImpl::kSignatureDef)) {
    return errors::Internal(
        "Failed to find 'signature_def' key in the GetModelMetadataResponse "
        "metadata map.");
  }
  bool unpack_status = response->metadata()
                           .at(GetModelMetadataImpl::kSignatureDef)
                           .UnpackTo(&signature_def_map);
  if (!unpack_status) {
    return errors::Internal(
        "Failed to unpack 'Any' object to 'SignatureDefMap'.");
  }

  string signature_def_output;
  const auto& status2 =
      MessageToJsonString(signature_def_map, &signature_def_output, opts);
  if (!status2.ok()) {
    return errors::Internal(
        "Failed to convert signature def proto to json. Error: ",
        status2.ToString());
  }

  // Concatenate the resulting strings into a valid JSON format.
  absl::StrAppend(output, "{\n");
  absl::StrAppend(output, "\"model_spec\":", model_spec_output, ",\n");
  absl::StrAppend(output, "\"metadata\": {");
  absl::StrAppend(output, "\"signature_def\": ", signature_def_output, "}\n");
  absl::StrAppend(output, "}\n");
  return Status::OK();
}

Status HttpRestApiHandler::GetInfoMap(
    const ModelSpec& model_spec, const string& signature_name,
    ::google::protobuf::Map<string, tensorflow::TensorInfo>* infomap) {
  ServableHandle<SavedModelBundle> bundle;
  TF_RETURN_IF_ERROR(core_->GetServableHandle(model_spec, &bundle));
  const string& signame =
      signature_name.empty() ? kDefaultServingSignatureDefKey : signature_name;
  auto iter = bundle->meta_graph_def.signature_def().find(signame);
  if (iter == bundle->meta_graph_def.signature_def().end()) {
    return errors::InvalidArgument("Serving signature name: \"", signame,
                                   "\" not found in signature def");
  }
  *infomap = iter->second.inputs();
  return Status::OK();
}

}  // namespace serving
}  // namespace tensorflow
<|endoftext|>


<commit_before>#define GetFS(b) ((b) & -(b))
#define ClrFS(b) (b &= ~GetFS(b))
// values of (1 << x) for x<32 are unique modulo 37
static const int m37pos[] = {
	32,  0,  1, 26,  2, 23, 27,  0,  3,
	16, 24, 30, 28, 11,  0, 13,  4,  7,
	17,  0, 25, 22, 31, 15, 29, 10, 12,
	 6,  0, 21, 14,  9,  5, 20,  8, 19, 18
};
#define Ctz(x) (m37pos[(x) % 37])

// Returns first integer with exactly n bits set
u32 popcnt_init(int n) { return (1 << n) - 1; }

// next higher number with same number of 1's in binary
u32 popcnt_next(u32 n)
{
	u32 c = (n & -n), r = n+c;
	return (((r ^ n) >> 2) / c) | r;
}

// Finds the most significant bit set on n. The bit is left in b, and its
// zero-indexed position in p
void msb(i64 n, i64 &b, int &p)
{
	for (b = 1, p = 0, n >>= 1; n; b <<= 1, n >>= 1, ++p);
}
<commit_msg>Edits to bitwise code<commit_after>#define PosLSB(x) (__builtin_ctzll(x))
#define GetLSB(x) ((x) & -(x))
#define ClrLSB(x) (x &= ~GetLSB(x))

#define PosMSB(x) (63 - __builtin_clzll(x))
#define GetMSB(x) (1ULL << PosMSB(x))

// Returns first integer with exactly n bits set
u32 popcnt_init(int n) { return (1 << n) - 1; }

// next higher number with same number of 1's in binary
u32 popcnt_next(u32 n)
{
	u32 c = (n & -n), r = n+c;
	return (((r ^ n) >> 2) / c) | r;
}

//
// Variants for non-gcc compilers
//

// values of (1 << x) for x<32 are unique modulo 37
static const int m37pos[] = {
	32,  0,  1, 26,  2, 23, 27,  0,  3,
	16, 24, 30, 28, 11,  0, 13,  4,  7,
	17,  0, 25, 22, 31, 15, 29, 10, 12,
	 6,  0, 21, 14,  9,  5, 20,  8, 19, 18
};
#define PosLSB(x) (m37pos[(x) % 37])

// Finds the most significant bit set on n. The bit is left in b, and its
// zero-indexed position in p
void msb(i64 n, i64 &b, int &p)
{
	for (b = 1, p = 0, n >>= 1; n; b <<= 1, n >>= 1, ++p);
}
<|endoftext|>


<commit_before>#include "vrayplugins.h"
#include "../common/albrdf.h"
#include "vraytexutils.h"
#include "bump_brdf_impl.h"

using namespace VR;

struct BRDFAlSurface_Params: VRayParameterListDesc {
	BRDFAlSurface_Params(void);
};

struct BRDFAlSurface: SimpleBSDF<MyBaseBSDF> {
	BRDFAlSurface(VRayPluginDesc *pluginDesc);
	void initBSDF(const VRayContext &rc, MyBaseBSDF *bsdf, VR::BSDFFlags flags) VRAY_OVERRIDE;
	int isOpaque(void) VRAY_OVERRIDE;

protected:
	TextureFloatInterface *opacity;
	BumpParams bumpParams;

	TextureInterface *diffuse;
	TextureFloatInterface *diffuseStrength;

	TextureInterface *reflect[2];
	TextureFloatInterface *reflectStrength[2];
	TextureFloatInterface *reflectRoughness[2];
	TextureFloatInterface *reflectIOR[2];
	int reflectDistribution[2];

	TextureFloatInterface *sssMix;
	int sssMode;
	float sssDensityScale;

	TextureFloatInterface *sssWeight[3];
	TextureInterface *sssColor[3];
	TextureFloatInterface *sssRadius[3];
};

#define BRDFAlSurface_PluginID PluginID(LARGE_CONST(2016082656))
PLUGIN_DESC(BRDFAlSurface_PluginID, EXT_BSDF, "BRDFAlSurface", BRDFAlSurface, BRDFAlSurface_Params);
PLUGIN_LIBRARY("BRDFAlSurface", "V-Ray port of the alSurface shader");

//************************************
// Implementation

#include "../common/default_values.h"

BRDFAlSurface_Params::BRDFAlSurface_Params(void) {
	addParamTextureFloat("bump_map", -1, "Overall bump map");
	addParamTextureFloat("bump_amount", 1.0f, -1, "Bump amount");
	addParamInt("bump_type", 0, -1, VRAY_BUMP_BRDF_MAP_TYPE_DESC, VRAY_BUMP_BRDF_MAP_TYPE_UIGUIDES);
	addParamTextureFloat("opacity", defaultOpacity, -1, "Opacity map", "minValue=(0), maxValue=(1)");

	addParamTexture("diffuse", defaultDiffuse, -1, "The diffuse surface color");
	addParamTextureFloat("diffuse_strength", defaultDiffuseStrength, -1, "The strength of the diffuse component", "minValue=(0), maxValue=(1)");

	addParamTexture("reflect1", defaultReflect1, -1, "The first specular color");
	addParamTextureFloat("reflect1_strength", defaultReflect1Strength, -1, "The strength of the first specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect1_roughness", defaultReflect1Roughness, -1, "The roughness of the first specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect1_ior", defaultReflect1IOR, -1, "The IOR for the first specular component");
	addParamInt("reflect1_distribution", 0, -1, "The BRDF distribution type for the first specular component (0 - Beckmann, 1 - GGX)", "enum=(0:Beckmann;1:GGX)");

	addParamTexture("reflect2", defaultReflect2, -1, "The second specular color");
	addParamTextureFloat("reflect2_strength", defaultReflect2Strength, -1, "The strength of the second specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect2_roughness", defaultReflect2Roughness, -1, "The roughness of the second specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect2_ior", defaultReflect2IOR, -1, "The IOR for the second specular component");
	addParamInt("reflect2_distribution", 0, -1, "The BRDF distribution type for the second specular component (0 - Beckmann, 1 - GGX)", "enum=(0:Beckmann;1:GGX)");

	addParamTextureFloat("sss_mix", defaultSSSMix, -1, "Mix between the diffuse component and the SSS component", "minValue=(0), maxValue=(1)");
	addParamInt("sss_mode", defaultSSSMode, -1, "Sub-surface scattering mode (0 - diffusion; 1 - directional)", "enum=(0:Diffusion;1:Directional)");
	addParamFloat("sss_density_scale", defaultSSSScale, -1, "Scale for the SSS effect; smaller values make light go deeper into the object");

	addParamTextureFloat("sss1_weight", defaultSSSWeight1, -1, "Weight of the first SSS component", "minValue=(0), maxValue=(1), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss1_color", defaultSSSColor1, -1, "Color of the first SSS component");
	addParamTextureFloat("sss1_radius", defaultSSSRadius1, -1, "Radius for the first SSS component. Larger values cause light to go deeper into the surface");

	addParamTextureFloat("sss2_weight", defaultSSSWeight2, -1, "Weight of the second SSS component", "minValue=(0), maxValue=(1), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss2_color", defaultSSSColor2, -1, "Color of the second SSS component");
	addParamTextureFloat("sss2_radius", defaultSSSRadius2, -1, "Radius for the second SSS component. Larger values cause light to go deeper into the surface");

	addParamTextureFloat("sss3_weight", defaultSSSWeight3, -1, "Weight of the third SSS component", "minValue=(0), maxValue=(1), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss3_color", defaultSSSColor3, -1, "Color of the third SSS component");
	addParamTextureFloat("sss3_radius", defaultSSSRadius3, -1, "Radius for the third SSS component. Larger values cause light to go deeper into the surface");
}

BRDFAlSurface::BRDFAlSurface(VRayPluginDesc *pluginDesc):SimpleBSDF<MyBaseBSDF>(pluginDesc) {
	paramList->setParamCache("bump_map", &bumpParams.bumpTexFloat);
	paramList->setParamCache("bump_amount", &bumpParams.bumpMultTex);
	paramList->setParamCache("bump_type", &bumpParams.mapType);
	paramList->setParamCache("opacity", &opacity);

	paramList->setParamCache("diffuse", &diffuse);
	paramList->setParamCache("diffuse_strength", &diffuseStrength);

	paramList->setParamCache("reflect1", &reflect[0]);
	paramList->setParamCache("reflect1_strength", &reflectStrength[0]);
	paramList->setParamCache("reflect1_roughness", &reflectRoughness[0]);
	paramList->setParamCache("reflect1_ior", &reflectIOR[0]);
	paramList->setParamCache("reflect1_distribution", &reflectDistribution[0]);

	paramList->setParamCache("reflect2", &reflect[1]);
	paramList->setParamCache("reflect2_strength", &reflectStrength[1]);
	paramList->setParamCache("reflect2_roughness", &reflectRoughness[1]);
	paramList->setParamCache("reflect2_ior", &reflectIOR[1]);
	paramList->setParamCache("reflect2_distribution", &reflectDistribution[1]);

	paramList->setParamCache("sss_mix", &sssMix);
	paramList->setParamCache("sss_mode", &sssMode);
	paramList->setParamCache("sss_density_scale", &sssDensityScale);

	paramList->setParamCache("sss1_weight", &sssWeight[0]);
	paramList->setParamCache("sss1_color", &sssColor[0]);
	paramList->setParamCache("sss1_radius", &sssRadius[0]);

	paramList->setParamCache("sss2_weight", &sssWeight[1]);
	paramList->setParamCache("sss2_color", &sssColor[1]);
	paramList->setParamCache("sss2_radius", &sssRadius[1]);

	paramList->setParamCache("sss3_weight", &sssWeight[2]);
	paramList->setParamCache("sss3_color", &sssColor[2]);
	paramList->setParamCache("sss3_radius", &sssRadius[2]);

	// We only have a bump texture, and it is multiplied by the bumpMult, so set the
	// bumpMult to 1.0 here.
	bumpParams.bumpMult=1.0f;
}

inline Color getTexture(const VRayContext &rc, TextureInterface *texmap, const VR::Color &defaultValue) {
	if (!texmap)
		return defaultValue;

	VR::Color color=texmap->getTexColor(rc).color;
	color.clampMinMax();
	return color;
}

inline float getTexture(const VRayContext &rc, TextureFloatInterface *texmap, float defaultValue, int clampValue=true) {
	if (!texmap)
		return defaultValue;

	float value=texmap->getTexFloat(rc);
	if (clampValue)
		value=clamp(value, 0.0f, 1.0f);

	return value;
}

void BRDFAlSurface::initBSDF(const VRayContext &rc, MyBaseBSDF *bsdf, VR::BSDFFlags flags) {
	VR::ALBSDFParams &params=bsdf->getParams();

	// Compute the bumped normal
	VR::Vector bumpVector(0.0f, 0.0f, 0.0f), bumpElevation(0.0f, 0.0f, 0.0f);
	bumpParams.getBump(rc, bumpVector, bumpElevation);

	// Save the current normal and hit point so that we can restore them later, in case they
	// are modified by bump mapping.
	Vector origNormal=rc.rayresult.normal;
	TracePoint origPoint=rc.rayresult.wpoint;

	// Before evaluating any textures, we must set the bumped normal as some
	// textures may depend on it.
	VRayContext &rcc=const_cast<VR::VRayContext&>(rc);
	applyBump(rcc, bumpVector, bumpElevation, bumpParams.mapType, rcc.rayresult.realBack);

	params.diffuse=getTexture(rc, diffuse, defaultDiffuse);
	params.diffuse*=getTexture(rc, diffuseStrength, defaultDiffuseStrength);

	params.reflectColor1=getTexture(rc, reflect[0], defaultReflect1);
	params.reflectColor1*=getTexture(rc, reflectStrength[0], defaultReflect1Strength);
	params.reflectRoughness1=getTexture(rc, reflectRoughness[0], defaultReflect1Roughness);
	params.reflectIOR1=getTexture(rc, reflectIOR[0], defaultReflect1IOR, false /* clamp */);
	params.reflectMode1=(reflectDistribution[0]==0? VR::alReflectDistribution_beckmann : VR::alReflectDistribution_GGX);

	params.reflectColor2=getTexture(rc, reflect[1], defaultReflect2);
	params.reflectColor2*=getTexture(rc, reflectStrength[1], defaultReflect2Strength);
	params.reflectRoughness2=getTexture(rc, reflectRoughness[1], defaultReflect2Roughness);
	params.reflectIOR2=getTexture(rc, reflectIOR[1], defaultReflect2IOR, false /* clamp */);
	params.reflectMode2=(reflectDistribution[1]==0? VR::alReflectDistribution_beckmann : VR::alReflectDistribution_GGX);

	params.transparency=1.0f-getTexture(rc, opacity, defaultOpacity);
	params.subdivs=8;
	params.doubleSided=true;

	params.sssMode=(sssMode==0? VR::alSSSMode_diffusion : VR::alSSSMode_directional);
	params.sssMix=getTexture(rc, sssMix, defaultSSSMix);
	params.sssDensityScale=sssDensityScale;

	params.sssWeight1=getTexture(rc, sssWeight[0], defaultSSSWeight1);
	params.sssColor1=getTexture(rc, sssColor[0], defaultSSSColor1);
	params.sssRadius1=getTexture(rc, sssRadius[0], defaultSSSRadius1, false  /* clamp */);

	params.sssWeight2=getTexture(rc, sssWeight[1], defaultSSSWeight2);
	params.sssColor2=getTexture(rc, sssColor[1], defaultSSSColor2);
	params.sssRadius2=getTexture(rc, sssRadius[1], defaultSSSRadius2, false  /* clamp */);

	params.sssWeight3=getTexture(rc, sssWeight[2], defaultSSSWeight3);
	params.sssColor3=getTexture(rc, sssColor[2], defaultSSSColor3);
	params.sssRadius3=getTexture(rc, sssRadius[2], defaultSSSRadius3, false  /* clamp */);

	params.normalizeWeights();

	bsdf->init(rc);

	// Restore the normal
	rcc.rayresult.normal=origNormal;
	rcc.rayresult.wpoint=origPoint;
}

int BRDFAlSurface::isOpaque(void) {
	int isSolid=false;
	if (!opacity) {
		isSolid=true;
	} else {
		float tmin=0.0f, tmax=1.0f;
		opacity->getTexFloatBounds(tmin, tmax);
		if (tmin>1.0f-1e-6f && tmax>1.0f-1e-6f)
			isSolid=true;
	}

	int res=0;
	if (isSolid) res|=MTL_OPAQUE_FOR_SHADOWS;

	return res;
}
<commit_msg>Adjust max values for the weights of the standalone plugin for auto UI generation.<commit_after>#include "vrayplugins.h"
#include "../common/albrdf.h"
#include "vraytexutils.h"
#include "bump_brdf_impl.h"

using namespace VR;

struct BRDFAlSurface_Params: VRayParameterListDesc {
	BRDFAlSurface_Params(void);
};

struct BRDFAlSurface: SimpleBSDF<MyBaseBSDF> {
	BRDFAlSurface(VRayPluginDesc *pluginDesc);
	void initBSDF(const VRayContext &rc, MyBaseBSDF *bsdf, VR::BSDFFlags flags) VRAY_OVERRIDE;
	int isOpaque(void) VRAY_OVERRIDE;

protected:
	TextureFloatInterface *opacity;
	BumpParams bumpParams;

	TextureInterface *diffuse;
	TextureFloatInterface *diffuseStrength;

	TextureInterface *reflect[2];
	TextureFloatInterface *reflectStrength[2];
	TextureFloatInterface *reflectRoughness[2];
	TextureFloatInterface *reflectIOR[2];
	int reflectDistribution[2];

	TextureFloatInterface *sssMix;
	int sssMode;
	float sssDensityScale;

	TextureFloatInterface *sssWeight[3];
	TextureInterface *sssColor[3];
	TextureFloatInterface *sssRadius[3];
};

#define BRDFAlSurface_PluginID PluginID(LARGE_CONST(2016082656))
PLUGIN_DESC(BRDFAlSurface_PluginID, EXT_BSDF, "BRDFAlSurface", BRDFAlSurface, BRDFAlSurface_Params);
PLUGIN_LIBRARY("BRDFAlSurface", "V-Ray port of the alSurface shader");

//************************************
// Implementation

#include "../common/default_values.h"

BRDFAlSurface_Params::BRDFAlSurface_Params(void) {
	addParamTextureFloat("bump_map", -1, "Overall bump map");
	addParamTextureFloat("bump_amount", 1.0f, -1, "Bump amount");
	addParamInt("bump_type", 0, -1, VRAY_BUMP_BRDF_MAP_TYPE_DESC, VRAY_BUMP_BRDF_MAP_TYPE_UIGUIDES);
	addParamTextureFloat("opacity", defaultOpacity, -1, "Opacity map", "minValue=(0), maxValue=(1)");

	addParamTexture("diffuse", defaultDiffuse, -1, "The diffuse surface color");
	addParamTextureFloat("diffuse_strength", defaultDiffuseStrength, -1, "The strength of the diffuse component", "minValue=(0), maxValue=(1)");

	addParamTexture("reflect1", defaultReflect1, -1, "The first specular color");
	addParamTextureFloat("reflect1_strength", defaultReflect1Strength, -1, "The strength of the first specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect1_roughness", defaultReflect1Roughness, -1, "The roughness of the first specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect1_ior", defaultReflect1IOR, -1, "The IOR for the first specular component");
	addParamInt("reflect1_distribution", 0, -1, "The BRDF distribution type for the first specular component (0 - Beckmann, 1 - GGX)", "enum=(0:Beckmann;1:GGX)");

	addParamTexture("reflect2", defaultReflect2, -1, "The second specular color");
	addParamTextureFloat("reflect2_strength", defaultReflect2Strength, -1, "The strength of the second specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect2_roughness", defaultReflect2Roughness, -1, "The roughness of the second specular component", "minValue=(0), maxValue=(1)");
	addParamTextureFloat("reflect2_ior", defaultReflect2IOR, -1, "The IOR for the second specular component");
	addParamInt("reflect2_distribution", 0, -1, "The BRDF distribution type for the second specular component (0 - Beckmann, 1 - GGX)", "enum=(0:Beckmann;1:GGX)");

	addParamTextureFloat("sss_mix", defaultSSSMix, -1, "Mix between the diffuse component and the SSS component", "minValue=(0), maxValue=(1)");
	addParamInt("sss_mode", defaultSSSMode, -1, "Sub-surface scattering mode (0 - diffusion; 1 - directional)", "enum=(0:Diffusion;1:Directional)");
	addParamFloat("sss_density_scale", defaultSSSScale, -1, "Scale for the SSS effect; smaller values make light go deeper into the object");

	addParamTextureFloat("sss1_weight", defaultSSSWeight1, -1, "Weight of the first SSS component", "minValue=(0), maxValue=(10), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss1_color", defaultSSSColor1, -1, "Color of the first SSS component");
	addParamTextureFloat("sss1_radius", defaultSSSRadius1, -1, "Radius for the first SSS component. Larger values cause light to go deeper into the surface");

	addParamTextureFloat("sss2_weight", defaultSSSWeight2, -1, "Weight of the second SSS component", "minValue=(0), maxValue=(10), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss2_color", defaultSSSColor2, -1, "Color of the second SSS component");
	addParamTextureFloat("sss2_radius", defaultSSSRadius2, -1, "Radius for the second SSS component. Larger values cause light to go deeper into the surface");

	addParamTextureFloat("sss3_weight", defaultSSSWeight3, -1, "Weight of the third SSS component", "minValue=(0), maxValue=(10), softMinValue=(0), softMaxValue=(1)");
	addParamTexture("sss3_color", defaultSSSColor3, -1, "Color of the third SSS component");
	addParamTextureFloat("sss3_radius", defaultSSSRadius3, -1, "Radius for the third SSS component. Larger values cause light to go deeper into the surface");
}

BRDFAlSurface::BRDFAlSurface(VRayPluginDesc *pluginDesc):SimpleBSDF<MyBaseBSDF>(pluginDesc) {
	paramList->setParamCache("bump_map", &bumpParams.bumpTexFloat);
	paramList->setParamCache("bump_amount", &bumpParams.bumpMultTex);
	paramList->setParamCache("bump_type", &bumpParams.mapType);
	paramList->setParamCache("opacity", &opacity);

	paramList->setParamCache("diffuse", &diffuse);
	paramList->setParamCache("diffuse_strength", &diffuseStrength);

	paramList->setParamCache("reflect1", &reflect[0]);
	paramList->setParamCache("reflect1_strength", &reflectStrength[0]);
	paramList->setParamCache("reflect1_roughness", &reflectRoughness[0]);
	paramList->setParamCache("reflect1_ior", &reflectIOR[0]);
	paramList->setParamCache("reflect1_distribution", &reflectDistribution[0]);

	paramList->setParamCache("reflect2", &reflect[1]);
	paramList->setParamCache("reflect2_strength", &reflectStrength[1]);
	paramList->setParamCache("reflect2_roughness", &reflectRoughness[1]);
	paramList->setParamCache("reflect2_ior", &reflectIOR[1]);
	paramList->setParamCache("reflect2_distribution", &reflectDistribution[1]);

	paramList->setParamCache("sss_mix", &sssMix);
	paramList->setParamCache("sss_mode", &sssMode);
	paramList->setParamCache("sss_density_scale", &sssDensityScale);

	paramList->setParamCache("sss1_weight", &sssWeight[0]);
	paramList->setParamCache("sss1_color", &sssColor[0]);
	paramList->setParamCache("sss1_radius", &sssRadius[0]);

	paramList->setParamCache("sss2_weight", &sssWeight[1]);
	paramList->setParamCache("sss2_color", &sssColor[1]);
	paramList->setParamCache("sss2_radius", &sssRadius[1]);

	paramList->setParamCache("sss3_weight", &sssWeight[2]);
	paramList->setParamCache("sss3_color", &sssColor[2]);
	paramList->setParamCache("sss3_radius", &sssRadius[2]);

	// We only have a bump texture, and it is multiplied by the bumpMult, so set the
	// bumpMult to 1.0 here.
	bumpParams.bumpMult=1.0f;
}

inline Color getTexture(const VRayContext &rc, TextureInterface *texmap, const VR::Color &defaultValue) {
	if (!texmap)
		return defaultValue;

	VR::Color color=texmap->getTexColor(rc).color;
	color.clampMinMax();
	return color;
}

inline float getTexture(const VRayContext &rc, TextureFloatInterface *texmap, float defaultValue, int clampValue=true) {
	if (!texmap)
		return defaultValue;

	float value=texmap->getTexFloat(rc);
	if (clampValue)
		value=clamp(value, 0.0f, 1.0f);

	return value;
}

void BRDFAlSurface::initBSDF(const VRayContext &rc, MyBaseBSDF *bsdf, VR::BSDFFlags flags) {
	VR::ALBSDFParams &params=bsdf->getParams();

	// Compute the bumped normal
	VR::Vector bumpVector(0.0f, 0.0f, 0.0f), bumpElevation(0.0f, 0.0f, 0.0f);
	bumpParams.getBump(rc, bumpVector, bumpElevation);

	// Save the current normal and hit point so that we can restore them later, in case they
	// are modified by bump mapping.
	Vector origNormal=rc.rayresult.normal;
	TracePoint origPoint=rc.rayresult.wpoint;

	// Before evaluating any textures, we must set the bumped normal as some
	// textures may depend on it.
	VRayContext &rcc=const_cast<VR::VRayContext&>(rc);
	applyBump(rcc, bumpVector, bumpElevation, bumpParams.mapType, rcc.rayresult.realBack);

	params.diffuse=getTexture(rc, diffuse, defaultDiffuse);
	params.diffuse*=getTexture(rc, diffuseStrength, defaultDiffuseStrength);

	params.reflectColor1=getTexture(rc, reflect[0], defaultReflect1);
	params.reflectColor1*=getTexture(rc, reflectStrength[0], defaultReflect1Strength);
	params.reflectRoughness1=getTexture(rc, reflectRoughness[0], defaultReflect1Roughness);
	params.reflectIOR1=getTexture(rc, reflectIOR[0], defaultReflect1IOR, false /* clamp */);
	params.reflectMode1=(reflectDistribution[0]==0? VR::alReflectDistribution_beckmann : VR::alReflectDistribution_GGX);

	params.reflectColor2=getTexture(rc, reflect[1], defaultReflect2);
	params.reflectColor2*=getTexture(rc, reflectStrength[1], defaultReflect2Strength);
	params.reflectRoughness2=getTexture(rc, reflectRoughness[1], defaultReflect2Roughness);
	params.reflectIOR2=getTexture(rc, reflectIOR[1], defaultReflect2IOR, false /* clamp */);
	params.reflectMode2=(reflectDistribution[1]==0? VR::alReflectDistribution_beckmann : VR::alReflectDistribution_GGX);

	params.transparency=1.0f-getTexture(rc, opacity, defaultOpacity);
	params.subdivs=8;
	params.doubleSided=true;

	params.sssMode=(sssMode==0? VR::alSSSMode_diffusion : VR::alSSSMode_directional);
	params.sssMix=getTexture(rc, sssMix, defaultSSSMix);
	params.sssDensityScale=sssDensityScale;

	params.sssWeight1=getTexture(rc, sssWeight[0], defaultSSSWeight1);
	params.sssColor1=getTexture(rc, sssColor[0], defaultSSSColor1);
	params.sssRadius1=getTexture(rc, sssRadius[0], defaultSSSRadius1, false  /* clamp */);

	params.sssWeight2=getTexture(rc, sssWeight[1], defaultSSSWeight2);
	params.sssColor2=getTexture(rc, sssColor[1], defaultSSSColor2);
	params.sssRadius2=getTexture(rc, sssRadius[1], defaultSSSRadius2, false  /* clamp */);

	params.sssWeight3=getTexture(rc, sssWeight[2], defaultSSSWeight3);
	params.sssColor3=getTexture(rc, sssColor[2], defaultSSSColor3);
	params.sssRadius3=getTexture(rc, sssRadius[2], defaultSSSRadius3, false  /* clamp */);

	params.normalizeWeights();

	bsdf->init(rc);

	// Restore the normal
	rcc.rayresult.normal=origNormal;
	rcc.rayresult.wpoint=origPoint;
}

int BRDFAlSurface::isOpaque(void) {
	int isSolid=false;
	if (!opacity) {
		isSolid=true;
	} else {
		float tmin=0.0f, tmax=1.0f;
		opacity->getTexFloatBounds(tmin, tmax);
		if (tmin>1.0f-1e-6f && tmax>1.0f-1e-6f)
			isSolid=true;
	}

	int res=0;
	if (isSolid) res|=MTL_OPAQUE_FOR_SHADOWS;

	return res;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: hlmarkwn.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: sj $ $Date: 2001-05-08 15:21:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_BKWND_HYPERLINK_HXX
#define _SVX_BKWND_HYPERLINK_HXX

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SVTREEBOX_HXX
#include <svtools/svtreebx.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring>
#endif

class SvxHyperlinkTabPageBase;

#define LERR_NOERROR        0
#define LERR_NOENTRIES      1
#define LERR_DOCNOTOPEN     2

//########################################################################
//#                                                                      #
//# Tree-Window                                                          #
//#                                                                      #
//########################################################################

class SvxHlinkDlgMarkWnd;

class SvxHlmarkTreeLBox : public SvTreeListBox
{
private:
    SvxHlinkDlgMarkWnd* mpParentWnd;

public:
    SvxHlmarkTreeLBox( Window* pParent, const ResId& rResId );

    virtual void Paint( const Rectangle& rRect );
};

//########################################################################
//#                                                                      #
//# Window-Class                                                         #
//#                                                                      #
//########################################################################

class SvxHlinkDlgMarkWnd : public ModalDialog //FloatingWindow
{
private:
    friend SvxHlmarkTreeLBox;

    PushButton      maBtApply;
    PushButton      maBtClose;
    //SvTreeListBox maLbTree;
    SvxHlmarkTreeLBox maLbTree;

    BOOL            mbUserMoved;
    BOOL            mbFirst;

    SvxHyperlinkTabPageBase* mpParent;

    String          maStrLastURL;

    USHORT          mnError;

protected:
    BOOL RefreshFromDoc( ::rtl::OUString aURL );

    SvLBoxEntry* FindEntry ( String aStrName );
    void ClearTree();
    int FillTree( ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xLinks, SvLBoxEntry* pParentEntry =NULL );

    virtual void Move ();

    DECL_LINK (ClickApplyHdl_Impl, void * );
    DECL_LINK (ClickCloseHdl_Impl, void * );

public:
    SvxHlinkDlgMarkWnd (SvxHyperlinkTabPageBase *pParent);
    ~SvxHlinkDlgMarkWnd();

    const BOOL MoveTo ( Point aNewPos );
    void RefreshTree ( String aStrURL );
    void SelectEntry ( String aStrMark );

    const BOOL ConnectToDialog( BOOL bDoit = TRUE );

    USHORT SetError( USHORT nError);
};

#endif  // _SVX_BKWND_HYPERLINK_HXX
<commit_msg>INTEGRATION: CWS ooo20031110 (1.2.464); FILE MERGED 2003/11/06 22:30:35 waratah 1.2.464.1: #i21906# add class after friend<commit_after>/*************************************************************************
 *
 *  $RCSfile: hlmarkwn.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2003-12-01 18:13:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_BKWND_HYPERLINK_HXX
#define _SVX_BKWND_HYPERLINK_HXX

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SVTREEBOX_HXX
#include <svtools/svtreebx.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring>
#endif

class SvxHyperlinkTabPageBase;

#define LERR_NOERROR        0
#define LERR_NOENTRIES      1
#define LERR_DOCNOTOPEN     2

//########################################################################
//#                                                                      #
//# Tree-Window                                                          #
//#                                                                      #
//########################################################################

class SvxHlinkDlgMarkWnd;

class SvxHlmarkTreeLBox : public SvTreeListBox
{
private:
    SvxHlinkDlgMarkWnd* mpParentWnd;

public:
    SvxHlmarkTreeLBox( Window* pParent, const ResId& rResId );

    virtual void Paint( const Rectangle& rRect );
};

//########################################################################
//#                                                                      #
//# Window-Class                                                         #
//#                                                                      #
//########################################################################

class SvxHlinkDlgMarkWnd : public ModalDialog //FloatingWindow
{
private:
    friend class SvxHlmarkTreeLBox;

    PushButton      maBtApply;
    PushButton      maBtClose;
    //SvTreeListBox maLbTree;
    SvxHlmarkTreeLBox maLbTree;

    BOOL            mbUserMoved;
    BOOL            mbFirst;

    SvxHyperlinkTabPageBase* mpParent;

    String          maStrLastURL;

    USHORT          mnError;

protected:
    BOOL RefreshFromDoc( ::rtl::OUString aURL );

    SvLBoxEntry* FindEntry ( String aStrName );
    void ClearTree();
    int FillTree( ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xLinks, SvLBoxEntry* pParentEntry =NULL );

    virtual void Move ();

    DECL_LINK (ClickApplyHdl_Impl, void * );
    DECL_LINK (ClickCloseHdl_Impl, void * );

public:
    SvxHlinkDlgMarkWnd (SvxHyperlinkTabPageBase *pParent);
    ~SvxHlinkDlgMarkWnd();

    const BOOL MoveTo ( Point aNewPos );
    void RefreshTree ( String aStrURL );
    void SelectEntry ( String aStrMark );

    const BOOL ConnectToDialog( BOOL bDoit = TRUE );

    USHORT SetError( USHORT nError);
};

#endif  // _SVX_BKWND_HYPERLINK_HXX
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

using namespace std;

constexpr unsigned int modulo {1000000007};

inline
void use_io_optimizations()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}

unsigned long long exponentiate(unsigned int base,
                                unsigned int exponent)
{
    unsigned long long result    {1};
    unsigned long long aggregate {base};

    for (auto i = exponent; i > 0; i /= 2)
    {
        if (i % 2 == 1)
        {
            result = (result * aggregate) % modulo;
        }

        aggregate = (aggregate * aggregate) % modulo;
    }

    return result;
}

int main()
{
    use_io_optimizations();

    unsigned int test_cases;
    cin >> test_cases;

    for (unsigned int test {0}; test < test_cases; ++test)
    {
        unsigned int sweets;
        cin >> sweets;

        if (sweets < 6)
        {
            cout << "FIGHT\n";
            continue;
        }

        unsigned long long ways {1};

        for (unsigned int i {sweets - 5}; i <= sweets - 1; ++i)
        {
            ways = (ways * i) % modulo;
        }

        cout << ways * exponentiate(120, modulo - 2) % modulo << '\n';
    }

    return 0;
}
<commit_msg>codechef; use a single line for functon arguments whenever possible<commit_after>#include <iostream>
#include <vector>

using namespace std;

constexpr unsigned int modulo {1000000007};

inline
void use_io_optimizations()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}

unsigned long long exponentiate(unsigned int base, unsigned int exponent)
{
    unsigned long long result    {1};
    unsigned long long aggregate {base};

    for (auto i = exponent; i > 0; i /= 2)
    {
        if (i % 2 == 1)
        {
            result = (result * aggregate) % modulo;
        }

        aggregate = (aggregate * aggregate) % modulo;
    }

    return result;
}

int main()
{
    use_io_optimizations();

    unsigned int test_cases;
    cin >> test_cases;

    for (unsigned int test {0}; test < test_cases; ++test)
    {
        unsigned int sweets;
        cin >> sweets;

        if (sweets < 6)
        {
            cout << "FIGHT\n";
            continue;
        }

        unsigned long long ways {1};

        for (unsigned int i {sweets - 5}; i <= sweets - 1; ++i)
        {
            ways = (ways * i) % modulo;
        }

        cout << ways * exponentiate(120, modulo - 2) % modulo << '\n';
    }

    return 0;
}
<|endoftext|>